如何在Dart中为HttpServer注册多个处理程序?

时间:2013-02-27 00:04:17

标签: dart

(我正在使用新的lib v2版本的dart:io。)

我想为HttpServer注册多个处理程序,特别是WebSocketTransformer和其他任意处理程序。像这样:

// pseudo-code

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

如果#1匹配,则不测试#2,依此类推。所以,这很贪心。

我看过只有一个处理程序的示例。如何注册多个处理程序?提前谢谢!

3 个答案:

答案 0 :(得分:3)

新答案:使用路线包:http://pub.dartlang.org/packages/route

以下是使用路由serve()方法的示例:

HttpServer.bind('127.0.0.1', 8889).then((server) {
  var router = new Router(server)
    ..serve('/ws').transform(new WebSocketTransformer()).listen(handleWebSocket)
    ..serve('/foo').listen((req) {
      req.response..addString('foo')..close();
    });
});

路由器自动捕获未处理的请求并发送404,但很快你就可以用你可以收听的defaultStream来覆盖它。

路由器还支持过滤器,对日志记录,身份验证,压缩等非常有用:

HttpServer.bind('127.0.0.1', 8889).then((server) {
  var router = new Router(server)
    ..filter(new RegExp(r'/.*'), (req) {
      //log all requests
      _logger.info("request: $req");
      return new Future.immediate(true); // keep processing request
    })
    ..filter(new Regexp(r'/secure/.*'), (req) {
      // check authentication asynchronously
      return getUserFromRequest(req).then((user) {
        if (user == null) {
          sendRedirect('/login'); // sendRedirect coming soon
          return false; // stop processing request
        } else {
          return true; // keep processing
        }
      });
    })
    ..serve(/* ... */ );
});

答案 1 :(得分:0)

以下是API docs建议注册WebSocket处理程序的方法:

server
    .where((request) => request.uri.path == "/ws")
    .transform(new WebSocketTransformer()).listen((webSocket) => ...);

但是,服务器是单订阅流。附加listen后,您无法附加其他侦听器。

我真正想要的是查看某个事件,决定是否可以处理它,如果是,则将其路由到另一个流。否则,传递它。这样,事件(在这种情况下是一个HttpRequest对象)就会沿链传递,直到它被处理完毕。

我构建了一个扩展TakeAndRoute的{​​{1}}类。 StreamEventTransformer使用一个函数来确定它是否应该抓取事件并将其路由到另一个流,或者只是将其转发。

以下是我提出的建议:

TakeAndRoute

不可否认,这可能有点矫枉过正。

答案 2 :(得分:0)

以下是一种更简洁,更简洁的方法:

  HttpServer.bind('127.0.0.1', 8889)
    .then((HttpServer server) {
      var sc = new StreamController();
      sc.stream.transform(new WebSocketTransformer()).listen(handleWebSocket);

      server.listen((HttpRequest request) {
        print("new connection from ${request.uri.scheme} ${request.uri}");

        // See https://code.google.com/p/dart/issues/detail?id=8825
        //if (request.uri.scheme == 'ws') {
        if (request.uri.path == '/ws') {
          sc.add(request);
        } else if (request.uri.path == '/foo') {
          request.response.addString('foo');
          request.response.close();
        } else {
          print("got 404 for ${request.uri}");
          request.response.statusCode = 404;
          request.response.close();
        }
      });
    });

注意我必须创建一个StreamController,以便将事件泵送到WebSocketTransformer