6

(私はdart:ioの新しいlib v2バージョンを使用しています。)

HttpServerに複数のハンドラー、具体的にはWebSocketTransformerとその他の任意のハンドラーを登録したいと思います。このようなもの:

// pseudo-code

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

#1が一致する場合、#2はテストされません。だから、それは貪欲です。

ハンドラーが1つしかないサンプルを見てきました。多くのハンドラーを登録するにはどうすればよいですか?前もって感謝します!

4

3 に答える 3

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(/* ... */ );
});
于 2013-03-09T22:08:13.287 に答える
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

于 2013-02-27T07:45:17.393 に答える
0

APIドキュメントがWebSocketハンドラーの登録を推奨する方法は次のとおりです。

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

ただし、サーバーは単一サブスクリプションストリームです。alistenをアタッチすると、他のリスナーをアタッチできなくなります。

私が本当に望んでいるのは、何かがイベントを見て、それを処理できるかどうかを判断し、処理できる場合は、別のストリームにルーティングすることです。それ以外の場合は、それを渡します。このようにして、イベント(この場合はHttpRequestオブジェクト)は、処理されるまでチェーンに沿って渡されます。

を拡張するTakeAndRouteクラスを作成しましたStreamEventTransformer。はTakeAndRoute関数を使用して、イベントを取得して別のストリームにルーティングするか、単に転送するかを決定します。

これが私が思いついたものです:

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

確かに、これはやり過ぎかもしれません。

于 2013-02-27T07:18:08.577 に答える