platform/lib/server.dart

114 lines
3.4 KiB
Dart
Raw Normal View History

2016-04-29 01:19:09 +00:00
///Exposes WebSocket functionality to Angel.
library angel_websocket.server;
import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'shared.dart';
2016-05-03 23:42:06 +00:00
List<WebSocket> sockets = [];
2016-04-29 01:19:09 +00:00
_respond(AngelMessage message, Service service, Angel app) async {
if (message.method == 'index') {
return await service.index(message.body['query']);
}
else if (message.method == 'read') {
return await service.read(message.body['id'], message.body['query']);
}
else if (message.method == 'modify') {
return await service.modify(
message.body['id'], message.body['data'] ?? {}, message.body['query']);
}
else if (message.method == 'update') {
2016-05-03 23:42:06 +00:00
await service.update(
2016-04-29 01:19:09 +00:00
message.body['id'], message.body['data'] ?? {}, message.body['query']);
}
else if (message.method == 'remove') {
2016-05-03 23:42:06 +00:00
await service.remove(message.body['id'], message.body['query']);
2016-04-29 01:19:09 +00:00
}
else throw new AngelHttpException.NotImplemented(
message: "This service does not support a \"${message
.method}\" method.");
}
_handleMsg(WebSocket socket, Angel app) {
return (msg) async {
String text = msg.toString();
try {
AngelMessage incoming = new AngelMessage.fromMap(
app.god.serializeToMap(text));
try {
Service service = app.service(incoming.service);
if (service == null) {
throw new AngelHttpException.NotFound(
message: 'The requested service does not exist.');
}
// Now, let's respond. :)
var result = await _respond(incoming, service, app);
AngelMessage response = new AngelMessage(
incoming.service, incoming.method, body: {'result': result});
socket.add(app.god.serialize(response));
} catch (e) {
AngelHttpException err = (e is AngelHttpException)
? e
: new AngelHttpException(e);
AngelMessage response = new AngelMessage(
incoming.service, incoming.method, body: err.toMap());
socket.add(app.god.serialize(response));
}
} catch (e) {
// If we are sent invalid data, we're not even going to
// bother responding. :)
}
};
}
2016-05-03 23:42:06 +00:00
_wireHooks(bool hookAll) {
return (Angel app) async {
for (Pattern path in app.services.keys) {
Service _service = app.services[path];
// Hook any unhooked services
if (!(_service is HookedService) && hookAll) {
app.services[path] = new HookedService(_service);
}
Service service = app.services[path];
if (service is HookedService) {
service.onIndexed.listen((List items) {
});
}
}
};
}
websocket({String endPoint: '/ws', bool hookAll: true}) {
2016-04-29 01:19:09 +00:00
return (Angel app) async {
app.get(endPoint, (RequestContext req, ResponseContext res) async {
if (WebSocketTransformer.isUpgradeRequest(req.underlyingRequest)) {
res
..end()
..willCloseItself = true;
WebSocket socket = await WebSocketTransformer.upgrade(
req.underlyingRequest);
2016-05-03 23:42:06 +00:00
sockets.add(socket);
socket.listen(_handleMsg(socket, app), onDone: () {
// Remove from cache on disconnect
sockets.remove(socket);
});
2016-04-29 01:19:09 +00:00
} else {
throw new AngelHttpException.BadRequest(
message: 'This endpoint is only available via WebSockets.');
}
});
2016-05-03 23:42:06 +00:00
await app.configure(_wireHooks(hookAll));
2016-04-29 01:19:09 +00:00
};
}