Oto jak API docs polecić zarejestrować obsługi websocket:
server
.where((request) => request.uri.path == "/ws")
.transform(new WebSocketTransformer()).listen((webSocket) => ...);
Jednak serwer jest strumień pojedynczej subskrypcji. Po dołączeniu listen
nie można dołączyć innych słuchaczy.
To, czego naprawdę chcę, to coś, co można zobaczyć na zdarzenie, zdecydować, czy może sobie z nim poradzić, a jeśli tak, to skierować je do innego strumienia. W przeciwnym razie przepuść to. W ten sposób zdarzenie (w tym przypadku obiekt HttpRequest) jest przekazywane wzdłuż łańcucha, dopóki nie zostanie obsłużone.
Zbudowałem klasę TakeAndRoute
, która rozszerza StreamEventTransformer
. TakeAndRoute
używa funkcji do określenia, czy powinien pobrać wydarzenie i skierować je do innego strumienia, lub po prostu przekazać dalej.
Oto co wymyśliłem:
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();
});
});
}
Trzeba przyznać, że to może być przesada.
To co szukałem, dzięki! –