2016-07-06 01:28:00 +00:00
|
|
|
part of angel_websocket.server;
|
|
|
|
|
2016-12-23 20:57:46 +00:00
|
|
|
/// Represents a WebSocket session, with the original
|
|
|
|
/// [RequestContext] and [ResponseContext] attached.
|
2016-07-06 01:28:00 +00:00
|
|
|
class WebSocketContext {
|
2016-12-23 20:57:46 +00:00
|
|
|
/// Use this to listen for events.
|
2021-02-21 02:47:23 +00:00
|
|
|
_WebSocketEventTable on = _WebSocketEventTable();
|
2016-12-23 20:57:46 +00:00
|
|
|
|
2018-11-04 02:11:52 +00:00
|
|
|
/// The underlying [StreamChannel].
|
|
|
|
final StreamChannel channel;
|
2016-12-23 20:57:46 +00:00
|
|
|
|
|
|
|
/// The original [RequestContext].
|
|
|
|
final RequestContext request;
|
|
|
|
|
|
|
|
/// The original [ResponseContext].
|
|
|
|
final ResponseContext response;
|
|
|
|
|
2021-04-10 15:12:43 +00:00
|
|
|
final StreamController<WebSocketAction> _onAction =
|
2021-02-21 02:47:23 +00:00
|
|
|
StreamController<WebSocketAction>();
|
2017-02-28 14:15:34 +00:00
|
|
|
|
2021-04-10 15:12:43 +00:00
|
|
|
final StreamController<void> _onAuthenticated = StreamController();
|
2019-02-03 19:44:53 +00:00
|
|
|
|
2021-04-10 15:12:43 +00:00
|
|
|
final StreamController<Null> _onClose = StreamController<Null>();
|
2017-02-28 14:15:34 +00:00
|
|
|
|
2021-04-10 15:12:43 +00:00
|
|
|
final StreamController _onData = StreamController();
|
2016-12-23 20:57:46 +00:00
|
|
|
|
|
|
|
/// Fired on any [WebSocketAction];
|
|
|
|
Stream<WebSocketAction> get onAction => _onAction.stream;
|
|
|
|
|
2019-02-03 19:44:53 +00:00
|
|
|
/// Fired when the user authenticates.
|
|
|
|
Stream<void> get onAuthenticated => _onAuthenticated.stream;
|
|
|
|
|
2017-02-28 14:15:34 +00:00
|
|
|
/// Fired once the underlying [WebSocket] closes.
|
|
|
|
Stream<Null> get onClose => _onClose.stream;
|
|
|
|
|
2017-09-24 16:19:16 +00:00
|
|
|
/// Fired when any data is sent through [channel].
|
2016-09-18 01:35:16 +00:00
|
|
|
Stream get onData => _onData.stream;
|
2016-07-06 01:28:00 +00:00
|
|
|
|
2017-09-24 16:19:16 +00:00
|
|
|
WebSocketContext(this.channel, this.request, this.response);
|
2016-07-06 01:28:00 +00:00
|
|
|
|
2018-11-04 02:11:52 +00:00
|
|
|
/// Closes the underlying [StreamChannel].
|
|
|
|
Future close() async {
|
2019-05-01 22:58:47 +00:00
|
|
|
scheduleMicrotask(() async {
|
|
|
|
await channel.sink.close();
|
|
|
|
await _onAction.close();
|
|
|
|
await _onAuthenticated.close();
|
|
|
|
await _onData.close();
|
2021-04-10 15:12:43 +00:00
|
|
|
_onClose.add(null);
|
2019-05-01 22:58:47 +00:00
|
|
|
await _onClose.close();
|
|
|
|
});
|
2017-02-28 14:15:34 +00:00
|
|
|
}
|
|
|
|
|
2016-12-23 20:57:46 +00:00
|
|
|
/// Sends an arbitrary [WebSocketEvent];
|
|
|
|
void send(String eventName, data) {
|
2021-02-21 02:47:23 +00:00
|
|
|
channel.sink.add(
|
|
|
|
json.encode(WebSocketEvent(eventName: eventName, data: data).toJson()));
|
2016-07-06 01:28:00 +00:00
|
|
|
}
|
|
|
|
|
2016-12-23 20:57:46 +00:00
|
|
|
/// Sends an error event.
|
2019-01-06 02:41:46 +00:00
|
|
|
void sendError(AngelHttpException error) => send(errorEvent, error.toJson());
|
2016-09-03 12:34:01 +00:00
|
|
|
}
|
2016-09-18 01:35:16 +00:00
|
|
|
|
|
|
|
class _WebSocketEventTable {
|
2021-04-10 15:12:43 +00:00
|
|
|
final Map<String, StreamController<Map>> _handlers = {};
|
2016-09-18 01:35:16 +00:00
|
|
|
|
2018-07-10 16:54:55 +00:00
|
|
|
StreamController<Map> _getStreamForEvent(String eventName) {
|
2021-04-10 15:12:43 +00:00
|
|
|
if (!_handlers.containsKey(eventName)) {
|
2021-02-21 02:47:23 +00:00
|
|
|
_handlers[eventName] = StreamController<Map>();
|
2021-04-10 15:12:43 +00:00
|
|
|
}
|
2016-09-18 01:35:16 +00:00
|
|
|
return _handlers[eventName];
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream<Map> operator [](String key) => _getStreamForEvent(key).stream;
|
|
|
|
}
|