2013-02-27 19 views
6

(używam nowej wersji v2 lib Dart: IO).Jak zarejestrować wiele programów obsługi dla HttpServer w Dart?

Chciałbym zarejestrować wiele teleskopowe dla HTTPServer, a konkretnie do WebSocketTransformer i innych dowolnych ładowarki. Coś takiego:

// pseudo-code 

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

Jeśli pasuje # 1, to # 2 nie jest testowane i tak dalej. Jest chciwy.

Widziałem próbki z tylko jednym przewodnikiem. Jak zarejestrować wiele programów obsługi? Z góry dziękuję!

Odpowiedz

3

Nowa odpowiedź: Za pomocą pakietu trasy : http://pub.dartlang.org/packages/route

Tu masz przykład stosując trasa jest serve() metody:

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

Router automatycznie przechwytuje nieobsłużone żądania i wysyła 404, choć wkrótce będziesz w stanie to zmienić poprzez defaultStream, którego możesz słuchać.

Router obsługuje również filtry, przydatne do logowania, uwierzytelniania, kompresja itp .:

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

To co szukałem, dzięki! –

0

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.

0

Oto bardziej ręczny, ale krótszy sposób to zrobić:

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

Wskazówki jak musiałem stworzyć StreamController więc może pompować zdarzenia WebSocketTransformer

Powiązane problemy