有没有办法使Dart服务器websocket实现与Phantom 1.9.7无头浏览器(另一个websocket标准)兼容?

时间:2014-06-14 17:27:17

标签: websocket dart phantomjs rfc6455

根据WebSocketTransformer文档,它表示会尝试根据HttpRequests网络套接字标准升级RFC6455

  

此转换器努力实现RFC6455指定的Web套接字。

并提供此Dart示例代码:

HttpServer server;
server.listen((request) {
  if (...) {
    WebSocketTransformer.upgrade(request).then((websocket) {
      ...
    });
  } else {
    // Do normal HTTP request processing.
  }
});

现在,如果您搜索PhantomJS的问题跟踪器,您可以找到问题:

11018 Update to final websocket standard

基本上说最新的PhantomJS(1.9.7)使用旧的Web套接字标准(我仍然没有弄清楚哪个版本发送了Sec-WebSocket-Key1信息,但我认为它不是RFC6455版本)

所以基本上,我的问题是当我运行PhantomJS无头浏览器到我的网站使用Dart 1.3.3,websocket服务器实现(基本上是我上面粘贴的一些升级代码)时,它说:

PhantomJS的标题:

  

sec-websocket-key1:327J w6iS / b!43 L2j5} 2 2
  连接:升级
  来源:http://mydomain.com
  升级:WebSocket
  sec-websocket-key2:42 d 7 64 84622
  主持人:mydomain.com

落镖:

  

WebSocketTransformer.isUpgradeRequest(request)= false

     

WebSocketException:无效的WebSocket升级请求

请求的升级失败(我假设它是因为版本的错误匹配)。

我的问题是,在Phantom JS使用2.0更新之前,有没有办法可以修复我的Dart后端,以便它也可以处理PhantomJS websockets?

根据WebSocketTransformer的文档,升级函数有两个参数,一个是HttpRequest必需参数,另一个是可选参数:

static Future<WebSocket> upgrade(HttpRequest request, {Function protocolSelector(List<String> protocols)})

这可能对我有所帮助吗?

3 个答案:

答案 0 :(得分:2)

协议不会帮助你。这些允许在握手通信之后使用的特殊协议达成一致。但是你不能自己修改握手和交换的字段。

你可以做的是制作一个完整的自己的websocket实现(直接基于Dart HTTP和TCP),它与PhantomJS使用的旧实现相匹配。但这不会与新客户合作。通过这种方式,您还可以创建支持多个版本的实现(通过在收到握手HTTP请求时检查标头,并根据握手转发到另一个实现。

您必须至少执行自己的WebSocketTransformer实施。为此,您可以从复制Darts界面和实现开始,并在您需要的所有位置修改它(检查许可证)。如果握手后的实际WebSocket行为在两个RFC中兼容,则可以重用Darts WebSocket类。如果不是这种情况(其他框架等),那么您还必须自己进行WebSocket课程。

基于你的一些伪代码:

HttpServer server;
server.listen((request) {
  if (...) { // websocket condition
    if (request.headers.value("Sec-WebSocket-Key1") != null) {
      YourWebSocketTransformer.upgrade(request).then((websocket) {
        ... // websocket might need to be a different type than Dart's WebSocket
      });
    } 
    else {
      WebSocketTransformer.upgrade(request).then((websocket) {
        ...
      });
    }
  }
  else {
    // Do normal HTTP request processing.
  }
});

我不知道你的应用程序,但它可能不值得付出努力。将旧的websocket实现带入Dart可能与将官方实现带入PhantomJS的努力相同。因此,我认为应该首选修复PhantomJS。

答案 1 :(得分:0)

&#34;无&#34;

HttpRequest.headers is immutable,因此您无法按照Dart愿意接受的格式按下请求标头。你不能做任何Ruby风格的猴子修补,因为Dart不允许进行动态评估。

可以,如果你选择疯狂的路径,当你看到一个带有预期标题的请求时,通过自己处理原始HttpRequest来实现兼容的WebSockets版本。我相信如果有必要,你可以重新实施WebSocket课程。 source for the WebSocket is here

答案 2 :(得分:0)

也许通过继承可以做到这一点。在飞镖中不可能避免压倒一切。 如果你有时间并且你真的需要这个,你可以重新实现一些方法来为PhatomJS补丁websocket

class MyWebSocket extends WebSocket {
    MyWebSocket(/* ... */) : super(/* ... */);

    methodYouNeedToOverride(/* ... */) {
        super.methodYouNeedToOverride(/* ... */)
        // Your patch
    }
}

这种方式可以让您访问&#34; protected&#34;变量或方法,可用于修补

但要小心,WebSocket只是可见部分,所有实现都在websocket_impl.dart