Ecco come il API docs consiglia di registrare un gestore WebSocket:
server
.where((request) => request.uri.path == "/ws")
.transform(new WebSocketTransformer()).listen((webSocket) => ...);
Tuttavia, il server è un flusso unico abbonamento. Una volta collegato a listen
, non è possibile allegare altri listener.
Quello che voglio veramente è che qualcosa guardi un evento, decidi se è in grado di gestirlo, e in tal caso lo instrado su un altro stream. Altrimenti, passalo. In questo modo, l'evento (in questo caso un oggetto HttpRequest) viene passato lungo una catena finché non viene gestito.
Ho creato una classe TakeAndRoute
che si estende StreamEventTransformer
. Il TakeAndRoute
utilizza una funzione per determinare se deve afferrare l'evento e instradarlo su un altro stream, o semplicemente inoltrarlo.
Ecco cosa mi è venuta:
import 'dart:io';
import 'dart:async';
handleWebSocket(WebSocket webSocket) {
webSocket.listen((event) {
if (event is MessageEvent) {
/* Handle message. */
} else if (event is CloseEvent) {
/* Handle closed. */
}
});
}
typedef bool ShouldTake(e);
typedef void RouteTo(Stream stream);
typedef void HandleEvent(e);
class TakeAndRoute<S, T> extends StreamEventTransformer<S, T> {
ShouldTake shouldTake;
RouteTo routeTo;
StreamController controller = new StreamController();
HandleEvent handler;
TakeAndRoute(this.shouldTake, {this.routeTo, this.handler}) {
if (routeTo != null) routeTo(controller.stream);
}
handleData(event, StreamSink sink) {
print("handling");
if (shouldTake(event)) {
if (routeTo != null) {
controller.add(event);
}
if (handler != null) {
handler(event);
}
} else {
sink.add(event);
}
}
}
main() {
HttpServer.bind('127.0.0.1', 8888)
.then((HttpServer server) {
server
.transform(new TakeAndRoute<HttpRequest, HttpRequest>(
(req) => req.uri.path == '/ws',
routeTo: (stream) => stream.transform(new WebSocketTransformer()).listen(handleWebSocket)))
.transform(new TakeAndRoute<HttpRequest, HttpRequest>(
(req) => req.uri.path == '/foo',
handler: (req) {
print('got foo');
req.response.addString("foo");
req.response.close();
}))
.listen((req) {
print("got 404 for ${req.uri}");
req.response.statusCode = 404;
req.response.close();
});
});
}
Certo, questo potrebbe essere eccessivo.
fonte
2013-02-27 07:18:08
Questo è quello che stavo cercando, grazie! –