4

我浏览了这里的论坛,这是我发现的最接近的问题:

如何在 WebSockets hybi 08+ 中(反)构造数据帧?

不同之处在于我无法成功握手。我假设在握手完成之前框架不会起作用,这是正确的吗?

当 Chrome 方便地更新到使用 HyBi 10 websocket 协议 ( https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-10 )的第 14 版时,我正要启动概念验证。根据握手规范中的信息(https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-10#section-5.2.2),我已经能够成功创建一个 Sec -WebSocket-Accept 键(根据他们的示例成功),但在客户端,socket.onopen 函数永远不会触发。

上次我遇到了 WebSocket 协议握手的问题,这是用正确的字节终止握手的问题(或者我认为字符更准确?)。我正在将 PHP 用于当前的实现,这意味着尝试解码 Python 或 C# 实现,但到目前为止没有成功。

这是我在 Chrome 14(适用于 Windows)中运行的客户端 Javascript:

var socket;
socket = new WebSocket(host);
socket.onopen = function(msg){
    // process onopen
};
socket.onmessage = function(msg){ 
    // process message
};
socket.close = function(msg){
    // process close
};

这是我用于握手的服务器端 PHP 代码:

function dohandshake($user,$buffer){
    // getheaders and calcKey are confirmed working, can provide source if desired
    list($resource,$host,$origin,$key,$version) = $this->getheaders($buffer);
    $request = "HTTP/1.1 101 Switching Protocols\r\n" .
            "Upgrade: WebSocket\r\n" .
            "Connection: Upgrade\r\n" .
            "Sec-WebSocket-Accept: " . $this->calcKey($key) . "\r\n";
    socket_write($user->socket,$request);
    $user->handshake=true;
    return true;
}

一旦客户端发送初始握手,Javascript 套接字就会无限期地保持在 CONNECTING 状态。这意味着 onopen 永远不会被触发,因此我的套接字处于不确定状态。关于如何调试甚至更好地确认我的握手方法的任何想法都会很棒。

这是 Python 中的一个明显(我不能说它是否有效)解决方案(https://github.com/kanaka/websockify/blob/master/websocket.py)。寻找 do_handshake 方法。

谢谢!

4

4 回答 4

5

所以我用握手解决了我的特殊问题,这很无聊。我需要两组“\r\n”来结束握手。因此,要解决我上面描述的握手问题(Javascript WebSocket 不会进入 OPEN 状态),我需要对我的服务器端 PHP 进行以下更改(注意末尾的 \r\n\r\n,doh) :

function dohandshake($user,$buffer){
    // getheaders and calcKey are confirmed working, can provide source if desired
    list($resource,$host,$origin,$key,$version) = $this->getheaders($buffer);
    $request = "HTTP/1.1 101 Switching Protocols\r\n" .
        "Upgrade: WebSocket\r\n" .
        "Connection: Upgrade\r\n" .
        "Sec-WebSocket-Accept: " . $this->calcKey($key) . "\r\n\r\n";
    socket_write($user->socket,$request);
    $user->handshake=true;
    return true;
}

同样对于未来的 PHP-WebSocket 爱好者,我只使用正则表达式来解析 getheaders 中的标头,这是 calcKey:

function calcKey($key){
     $CRAZY = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
     $sha = sha1($key.$CRAZY,true);
     return base64_encode($sha);
}

希望这对其他人有帮助!现在开始处理消息框架......

于 2011-08-14T15:40:56.770 回答
1

这是我对这个问题的解决方案。如果在遥远的将来某个时候此代码停止工作,请在此处发布!

https://github.com/esromneb/phpwebsocket/blob/master/websocket.class.php

查看我的播客了解更多黑客技巧! http://portforwardpodcast.com/

于 2011-10-20T03:15:58.490 回答
0

如果可以,xsockets.net 在 c# 中提供服务器端解决方案?但是,您不需要编写任何服务器端代码来执行您在上面尝试执行的操作。使用通用处理程序并且只编写 JavaScript。

XSockets 具有高达 hybi10 的多协议支持,具有跨浏览器功能并回退到 silverlight 和 flash。如果您想编写自己的协议等,还支持协议、处理程序和拦截器的插件......请参阅http://youtu.be/MDz1jJJeXKI?hd=1上的演示

http://xsockets.net/Documentation/Index上的文档

最好的问候乌菲

于 2011-08-14T07:28:03.247 回答
0

另一件事......你可以在 JsBin 上测试对 hybi10 的支持。那里有一个包含所有可编辑代码的多房间聊天。

不过那里没有闪光灯和银光后备!

http://jsbin.com/ohitil

/乌菲

于 2011-08-14T07:46:58.397 回答