2013-02-27 38 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

相關問題