2013-02-27 83 views
6

(我使用的镖的新LIB V2版本:10。)如何在Dart中为HttpServer注册多个处理程序?

我想一个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

新的答案:使用路由包: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(/* ... */); 
}); 
+0

这就是我一直在寻找,谢谢! – 2013-03-10 16:15:25

0

这里的API docs如何推荐注册的WebSocket处理程序:

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

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

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

我建立了一个TakeAndRoute类,延伸StreamEventTransformerTakeAndRoute使用一个函数来确定它是否应该抓取事件并将其路由到另一个流,或者简单地将其转发。

这就是我想出了:

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

诚然,这可能是矫枉过正。

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