part of angel_websocket.server; /// Represents a WebSocket session, with the original /// [RequestContext] and [ResponseContext] attached. class WebSocketContext { /// Use this to listen for events. _WebSocketEventTable on = new _WebSocketEventTable(); /// The underlying [StreamChannel]. final StreamChannel channel; /// The original [RequestContext]. final RequestContext request; /// The original [ResponseContext]. final ResponseContext response; StreamController _onAction = new StreamController(); StreamController _onClose = new StreamController(); StreamController _onData = new StreamController(); /// Fired on any [WebSocketAction]; Stream get onAction => _onAction.stream; /// Fired once the underlying [WebSocket] closes. Stream get onClose => _onClose.stream; /// Fired when any data is sent through [channel]. Stream get onData => _onData.stream; WebSocketContext(this.channel, this.request, this.response); /// Closes the underlying [StreamChannel]. Future close() async { await channel.sink.close(); _onAction.close(); _onData.close(); _onClose.add(null); _onClose.close(); } /// Sends an arbitrary [WebSocketEvent]; void send(String eventName, data) { channel.sink.add(json .encode(new WebSocketEvent(eventName: eventName, data: data).toJson())); } /// Sends an error event. void sendError(AngelHttpException error) => send(EVENT_ERROR, error.toJson()); } class _WebSocketEventTable { Map> _handlers = {}; StreamController _getStreamForEvent(String eventName) { if (!_handlers.containsKey(eventName)) _handlers[eventName] = new StreamController(); return _handlers[eventName]; } Stream operator [](String key) => _getStreamForEvent(key).stream; }