带有 hybi-17 的 HTML5 WebSocket
Posted
技术标签:
【中文标题】带有 hybi-17 的 HTML5 WebSocket【英文标题】:HTML5 WebSocket with hybi-17 【发布时间】:2011-12-18 04:55:12 【问题描述】:更新:我解决了解码问题,感谢pimvdb
遵循解决方案(在 php 中):
$len = $masks = $data = $decoded = null;
$len = ord ($buffer[1]) & 127;
if ($len === 126)
$masks = substr ($buffer, 4, 4);
$data = substr ($buffer, 8);
else if ($len === 127)
$masks = substr ($buffer, 10, 4);
$data = substr ($buffer, 14);
else
$masks = substr ($buffer, 2, 4);
$data = substr ($buffer, 6);
for ($index = 0; $index < strlen ($data); $index++)
$decoded .= $data[$index] ^ $masks[$index % 4];
*** 原题目的开始 ***
我正在尝试使用 hybi-17 handshake 为个人应用程序开发 html5 WebSocket。
我是从phpwebsocket开始的,我唯一改变的是握手功能,从原来的变成了这个:
function dohandshake($user,$buffer)
$key = null;
console("\nRequesting handshake...");
console($buffer);
console("Handshaking...");
preg_match ("#Sec-WebSocket-Key: (.*?)\r\n#", $buffer, $match) && $key = $match[1];
$key .= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
$key = sha1 ($key);
$key = pack ('H*', $key);
$key = base64_encode ($key);
$upgrade =
"HTTP/1.1 101 Switching Protocols\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"Sec-WebSocket-Accept: $key\r\n\r\n";
socket_write($user->socket,$upgrade.chr(0),strlen($upgrade.chr(0)));
$user->handshake=true;
console($upgrade);
console("Done handshaking...");
return true;
我为 client (http://code.google.com/p/phpwebsocket/source/browse/trunk/+phpwebsocket/client.html) 和 server (http://code.google.com/p/phpwebsocket/source/browse/trunk/+phpwebsocket/server.php) 使用了 phpwebsocket 源代码。
此时,我测试了应用程序。跟随服务器调试:
Server Started : 2011-10-30 13:45:41
Master socket : Resource id #4
Listening on : localhost port 12345
Resource id #5 CONNECTED!
Requesting handshake...
GET /phpwebsocket/server.php HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost:12345
Sec-WebSocket-Origin: http://localhost
Sec-WebSocket-Key: +S/J2jcp/UKIS1HTW0n1/w==
Sec-WebSocket-Version: 8
Handshaking...
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: LEULWidwXDxY02iv3O+xksrxFz4=
Done handshaking...
< ��z�p
> ��z�p not understood
Resource id #5 DISCONNECTED!
这是客户端调试:
WebSocket - status 0
Welcome - status 1
Sent: hello
Disconnected - status 3
我所做的只是连接客户端并发送命令“Hello”。 如您所见,服务器收到的是编码数据而不是明文:为什么?
我正在寻找帮助我使用 hybi-17 开发 html5 websocket 的人。
齐亚兹
PS:this (Implementing handshake for hybi-17) 主题和this one (Decoding network chars (HTML5 Websocket)) 可能会有所帮助。
PPS:我在 Chromium 15.0.874.106~r107270-0ubuntu0.11.04.1
上进行了测试【问题讨论】:
你需要对你获得的消息进行解码; hybi 包含一个相对复杂的框架机制(与 hixie 草案相比)。您不能“仅”读取传入的字节。我之前在***.com/questions/7040078/…发布了一些解码算法。 谢谢 pimvdb!我做到了!现在您可以在原始主题顶部查看解决方案;) Cyaz 对不起 pimvdb 但我对有效载荷长度有一些问题。好吧,当我尝试使用 $msg[1] & 127(或 0x7F)获取长度时,我总是得到“0”。在我的特殊情况下,缓冲区不是数组而是字符串:因此代码将是 substr($msg, 1, 1) & 127。无论如何它都不起作用。为什么?为什么我无法按照您的指示获得有效载荷长度?有什么想法吗? 我对 PHP 几乎一无所知,但是如果您使用的是字符串,那么底层的字符代码就代表了这些值。你当然不能character & 127
;它只适用于数字。你最好构建一个数组,其中每个元素对应字符串中的字符代码。
点赞:codepad.org/EiubBUSl.
【参考方案1】:
这个编码功能很棒,只是 chrome 19 不喜欢被屏蔽的数据。将第一条消息发送到服务器后出现此错误: “服务器不得屏蔽它发送给客户端的任何帧。”
直到我找到一个有效的 github 示例并且有一个可以设置为不屏蔽数据帧的标志之前,我无法弄清楚如何不屏蔽发送到服务器的数据。 https://github.com/lemmingzshadow/php-websocket
我发现了这个更新版本的 phpwebsocket 代码: http://www.wilky.it/phpwebsocket-new-version/ 您需要解决的一件事是在第 234 行替换此行: preg_match ("#Sec-WebSocket-Origin: (.*?)\r\n#", $buffer, $match) && $origin = $match[1]; 和 preg_match ("#Origin: (.*?)\r\n#", $buffer, $match) && $origin = $match[1];
然后修复 chrome 中的错误:“服务器不得屏蔽它发送给客户端的任何帧。”请执行下列操作: 我用 lemmingzshadow 的 github 中的 connection.php 文件修复了替换的编码函数,它开始工作了。函数调用:\server\lib\WebSocket\connection.php 文件中的 hybi10Encode。 在函数编码中更改此参数:$masked = true 为 $masked = false 所以我们现在有 2 个版本可以在 chrome 和 firefox 12 中运行!
【讨论】:
【参考方案2】:解码解决方案(感谢@pimvdb):
$len = $masks = $data = $decoded = null;
$len = ord ($buffer[1]) & 127;
if ($len === 126)
$masks = substr ($buffer, 4, 4);
$data = substr ($buffer, 8);
else if ($len === 127)
$masks = substr ($buffer, 10, 4);
$data = substr ($buffer, 14);
else
$masks = substr ($buffer, 2, 4);
$data = substr ($buffer, 6);
for ($index = 0; $index < strlen ($data); $index++)
$decoded .= $data[$index] ^ $masks[$index % 4];
【讨论】:
你(和@pimvdb)刚刚救了我的命。谢谢!以上是关于带有 hybi-17 的 HTML5 WebSocket的主要内容,如果未能解决你的问题,请参考以下文章
Html5之高级-14 Web Socket(概述API示例)
如何从不支持 HTML5 的旧浏览器绑定到 Web 套接字服务器