platform/lib/websocket_controller.dart

97 lines
2.9 KiB
Dart
Raw Normal View History

2016-09-18 02:53:58 +00:00
part of angel_websocket.server;
2017-01-29 20:02:19 +00:00
/// Marks a method as available to WebSockets.
2016-09-18 02:53:58 +00:00
class ExposeWs {
final String eventName;
const ExposeWs(this.eventName);
}
2017-01-29 20:02:19 +00:00
/// A special controller that also supports WebSockets.
2016-09-18 02:53:58 +00:00
class WebSocketController extends Controller {
Map<String, MethodMirror> _handlers = {};
Map<String, Symbol> _handlerSymbols = {};
2017-01-29 20:02:19 +00:00
/// The plug-in instance powering this controller.
AngelWebSocket plugin;
2016-09-18 02:53:58 +00:00
2016-12-23 20:57:46 +00:00
WebSocketController() : super();
2017-01-29 20:02:19 +00:00
/// Sends an event to all clients.
void broadcast(String eventName, data, {filter(WebSocketContext socket)}) {
plugin.batchEvent(new WebSocketEvent(eventName: eventName, data: data),
filter: filter);
2016-09-18 02:53:58 +00:00
}
2017-01-29 20:02:19 +00:00
/// Fired on new connections.
2016-12-23 20:57:46 +00:00
onConnect(WebSocketContext socket) {}
2017-01-29 20:02:19 +00:00
/// Fired on disconnections.
2016-12-23 20:57:46 +00:00
onDisconnect(WebSocketContext socket) {}
2017-01-29 20:02:19 +00:00
/// Fired on all incoming actions.
2016-12-23 20:57:46 +00:00
onAction(WebSocketAction action, WebSocketContext socket) async {}
2017-01-29 20:02:19 +00:00
/// Fired on arbitrary incoming data.
2016-12-23 20:57:46 +00:00
onData(data, WebSocketContext socket) {}
2016-09-18 02:53:58 +00:00
@override
Future call(Angel app) async {
await super.call(app);
2016-12-23 20:57:46 +00:00
InstanceMirror instanceMirror = reflect(this);
2016-09-18 02:53:58 +00:00
ClassMirror classMirror = reflectClass(this.runtimeType);
classMirror.instanceMembers.forEach((sym, mirror) {
if (mirror.isRegularMethod) {
InstanceMirror exposeMirror = mirror.metadata.firstWhere(
(mirror) => mirror.reflectee is ExposeWs,
orElse: () => null);
if (exposeMirror != null) {
ExposeWs exposeWs = exposeMirror.reflectee;
_handlers[exposeWs.eventName] = mirror;
_handlerSymbols[exposeWs.eventName] = sym;
}
}
});
AngelWebSocket ws = app.container.make(AngelWebSocket);
ws.onConnection.listen((socket) async {
2016-12-23 20:57:46 +00:00
socket.request
..inject('socket', socket)
..inject(WebSocketContext, socket);
2016-09-18 02:53:58 +00:00
await onConnect(socket);
2016-12-23 20:57:46 +00:00
socket.onData.listen((data) => onData(data, socket));
2016-09-18 02:53:58 +00:00
2016-12-23 20:57:46 +00:00
socket.onAction.listen((WebSocketAction action) async {
2017-04-15 19:02:17 +00:00
socket.request.inject(WebSocketAction, action);
2016-12-23 20:57:46 +00:00
await onAction(action, socket);
2016-09-18 02:53:58 +00:00
2016-12-23 20:57:46 +00:00
if (_handlers.containsKey(action.eventName)) {
2016-09-18 02:53:58 +00:00
try {
2016-12-23 20:57:46 +00:00
var methodMirror = _handlers[action.eventName];
var fn = instanceMirror.getField(methodMirror.simpleName).reflectee;
return app.runContained(fn, socket.request, socket.response);
} catch (e, st) {
2016-09-18 02:53:58 +00:00
// Send an error
if (e is AngelHttpException)
socket.sendError(e);
2016-12-23 20:57:46 +00:00
else if (ws.debug == true)
socket.sendError(new AngelHttpException(e,
message: e.toString(),
stackTrace: st,
errors: [st.toString()]));
2016-09-18 02:53:58 +00:00
else
socket.sendError(new AngelHttpException(e));
}
}
});
});
2016-09-18 03:16:51 +00:00
ws.onDisconnection.listen(onDisconnect);
2016-09-18 02:53:58 +00:00
}
}