Wednesday, September 4, 2013

Mixing WebSocket and HttpRequest

http://stackoverflow.com/questions/15101858/how-do-i-register-multiple-handlers-for-a-httpserver-in-dart

// pseudo-code

var server = HttpServer;
server.register('/foo', someHandlerFunction);        // 1
server.register('/bar', someOtherHandlerFunction);   // 2
server.register('/ws', webSocketHandler);            // 3

===>
Recommended Approach

----------------
 
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();
        });
    });
}

No comments:

Post a Comment