2014-10-03 50 views
3

https://pub.dartlang.org/packages/shelf_web_socket HTTP和WS请求显示这个例子如何使用shelf_web_socket侦听同一端口

import 'package:shelf/shelf_io.dart' as shelf_io; 
import 'package:shelf_web_socket/shelf_web_socket.dart'; 

void main() { 
    var handler = webSocketHandler((webSocket) { 
    webSocket.listen((message) { 
     webSocket.add("echo $message"); 
    }); 
    }); 

    shelf_io.serve(handler, 'localhost', 8080).then((server) { 
    print('Serving at ws://${server.address.host}:${server.port}'); 
    }); 
} 

我想知道如何将它与我的HTTP服务器初始化结合

import 'package:shelf/shelf.dart' as shelf; 
import 'package:shelf/shelf_io.dart' as sIo; 
import 'package:shelf_auth/shelf_auth.dart' as sAuth; 
import 'package:shelf_auth/src/authentication.dart' as sAuth2; 
import 'package:option/option.dart'; 
import 'package:shelf_web_socket/shelf_web_socket.dart' as sWs; 

... 

var authMiddleware = sAuth.authenticate(
    [new MyAuthenticator()], 
    sessionHandler: new sAuth.JwtSessionHandler('bla', 'blub', new UserLookup()), 
    allowHttp: true, 
    allowAnonymousAccess: false); 

var handler = const shelf.Pipeline() 
    .addMiddleware(shelf.logRequests()) 
    .addMiddleware(authMiddleware) 
    .addHandler(_handleHttpRequest); 

// var wsHandler = sWs.webSocketHandler(_handleWebSocketConnect); 

sIo.serve(handler, '0.0.0.0', servePort).then((server) { 
    _log.finest('Serving at http://${server.address.host}:${server.port}'); 
}); 

需要做些什么才能使wsHandler被WebSocket连接调用,handler一直处理HTTP请求(如果可能的话在同一个端口上),并且如果可能的话使用configure d认证和会话管理。

我尝试了不同的端口上,但与认证/会话中间件(不知道如果这是应该一起使用)

var authMiddleware = sAuth.authenticate(
     [new MyAuthenticator()], 
     sessionHandler: new sAuth.JwtSessionHandler('bla', 'blub', new UserLookup()), 
     allowHttp: true, 
     allowAnonymousAccess: false); 

    var handler = const shelf.Pipeline() 
     .addMiddleware(shelf.logRequests()) 
     .addMiddleware(authMiddleware) 
     .addHandler(_handleHttpRequest); 

    sIo.serve(handler, '0.0.0.0', servePort).then((server) { 
     _log.finest('Serving at http://${server.address.host}:${server.port}'); 
    }); 


    var wsHandler = const shelf.Pipeline() 
     .addMiddleware(shelf.logRequests()) 
     .addMiddleware(authMiddleware) 
     .addHandler(sWs.webSocketHandler(_handleWebSocketConnect)); 

    sIo.serve(wsHandler, '0.0.0.0', servePort + 1).then((server) { 
     _log.finest('Serving at ws://${server.address.host}:${server.port}'); 
    }); 

,并得到

Illegal argument(s): webSocketHandler may only be used with a server that supports request hijacking. 

回答

3

此刻你根处理程序是http处理程序。您需要设置一个处理程序,该处理程序有条件地将请求发送给ws处理程序或其他处理程序以处理您的http请求。例如

/WS - >您的WS处理程序

/休息 - >您的其他处理器

做到这一点的最简单的方法是使用像shelf_route路由器。

但是最近有人试过这个,并且击中bug in shelf that stopped this working。正如你在下面指出的那样是固定但不合并。

一旦问题是固定的,你应该能够做到

import 'package:shelf/shelf.dart' as shelf; 
import 'package:shelf/shelf_io.dart' as io; 
import 'package:shelf_route/shelf_route.dart' as route; 
import 'package:shelf_web_socket/shelf_web_socket.dart' as sWs; 
import 'package:shelf_auth/shelf_auth.dart' as sAuth; 
import 'dart:async'; 
import 'package:option/option.dart'; 
import 'package:shelf_exception_response/exception_response.dart'; 

void main(List<String> arguments) { 

    var authMiddleware = sAuth.authenticate(
     [new MyAuthenticator()], 
     sessionHandler: new sAuth.JwtSessionHandler('bla', 'blub', new UserLookup()), 
     allowHttp: true, 
     allowAnonymousAccess: false); 


    var router = (route.router() 
     ..get('/rest', _handleHttpRequest) 
     ..get('/ws', sWs.webSocketHandler(_handleWebSocketConnect))); 

    var handler = const shelf.Pipeline() 
     .addMiddleware(exceptionResponse()) 
     .addMiddleware(shelf.logRequests()) 
     .addMiddleware(authMiddleware) 
     .addHandler(router.handler); 

    route.printRoutes(router); 

    io.serve(handler, '127.0.0.1', 8080).then((server) { 
    print('Serving at http://${server.address.host}:${server.port}'); 
    }); 
} 

,直到问题得到固定,你可以用

var hackyRouterHandler = (shelf.Request request) { 
    var path = request.url.path; 
    if (path.startsWith('/rest')) { 
    return _handleHttpRequest(request); 
    } 
    else if (path.startsWith('/ws')) { 
    return sWs.webSocketHandler(_handleWebSocketConnect)(request); 
    } 
    else { 
    throw new NotFoundException(); 
    } 
}; 
+0

大更换router.handler!感谢您的支持。 – 2014-10-03 07:00:44

+1

与此同时,您可以查看https://groups.google.com/a/dartlang.org/forum/m/#!searchin/misc/shelf/misc/PrkSD9iVISs 它有这样一个例子。不幸的是,它看起来像架子问题尚未修复。这太遗憾了,因为它是如此小的变化 – Anders 2014-10-03 07:29:49

+0

感谢您的链接!我不得不删除'm /'来使它工作。 – 2014-10-03 07:32:01