根据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)})
这可能对我有所帮助吗?
答案 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