Chrome 17中缺少'Sec-WebSocket-Accept'头

12

编辑: 我尝试了这个phpwebsocket: http://www.wilky.it/Shared/phpwebsocket.zip,在Firefox中可以工作,但我的问题仍然存在:如何让websockets在Chrome 17中与php服务器一起工作?


我正在按照这里的教程进行操作:http://net.tutsplus.com/tutorials/javascript-ajax/start-using-html5-websockets-today/

看起来客户端连接后立即断开了。我在控制台中看到了这个错误:

WebSocket握手期间发生错误:缺少'Sec-WebSocket-Accept'头

我正在Chrome 17.0.963.56上尝试,在我的WAMP本地主机上启用了php_sockets扩展。

我看到有人提到Chrome已经改变了它所支持的内容,但它没有深入说明如何解决问题。我希望有人能够指导我。(我是完全新手)。

服务器:

{PATH}>php startDaemon.php

2012-02-20 07:02:51 系统:套接字资源id#7已创建。

2012-02-20 07:02:51 系统:套接字绑定到localhost:8000。

2012-02-20 07:02:51 系统:开始侦听套接字。

2012-02-20 07:03:01 WebSocket:资源id#8已连接!

2012-02-20 07:03:01 WebSocket:正在请求握手...

2012-02-20 07:03:01 WebSocket:正在握手...

2012-02-20 07:03:01 WebSocket:握手完成...

2012-02-20 07:03:01 WebSocket:资源id#8已断开连接!

客户端:

套接字状态:0

套接字状态:3(已关闭)


1
如果您能打印接收到的握手和整个响应发送,那将会很有帮助。错误表明缺少Accept值,但是如果没有看到握手请求和响应,很难知道具体情况。我注意到您链接的服务器在响应中返回了太多字段。 - kanaka
我正在使用那个链接中的代码。我不确定你具体在问什么? - allicarn
我请求您在代码中添加仪器,以打印出握手请求(来自浏览器)和响应(来自服务器)。 - kanaka
我认为你正在使用这个项目:https://github.com/GeorgeNava/phpwebsocket,但是在我看来,最好使用这个分支项目:https://github.com/esromneb/phpwebsocket。这个项目运行良好,没有缺失的`Sec-WebSocket-Accept`。 - Nabi K.A.Z.
3个回答

1

我有同样的问题(似乎无法在此处发表评论,因此我回复了)。

实际上,我刚刚下载并测试了phpwebsocket。

在Safari 5.1.4上,它可以正常工作。

在Chrome 17上,我在脚本日志控制台中得到了相同的错误:

Error during WebSocket handshake: 'Sec-WebSocket-Accept' header is missing

所以,在websocket.class.php中,我添加了服务器返回的头部:

$accept = base64_encode(SHA1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));

我收到了错误信息:

Error during WebSocket handshake: Sec-WebSocket-Accept mismatch

现在,服务器收到的头部是:

GET /websocket/server.php HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost:12345
Origin: http://localhost:8888
Sec-WebSocket-Key: OqMJI0t/cOl6d6JNE+Op0g==
Sec-WebSocket-Version: 13

服务器返回的标头为:
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://localhost:8888
Sec-WebSocket-Location: ws://localhost:12345/websocket/server.php
Sec-WebSocket-Accept: ZjY5ODliNTViYzJlOTNkMjk4OTg3Y2U2NjQ3MTBlZjZiNzliYzk4Yg==

Sec-WebSocket-Accept 看起来不错,但仍然存在不匹配的错误。你看到哪里有错误吗?也许协议已经改变以计算 Sec-WebSocket-Accept,但我找不到它...感谢你的帮助!

编辑:这似乎是解决方案(至少对我来说):在 SHA1 函数中添加参数 true,如 this issue thread 中给出的文件中所找到的。因此,必须像这样找到 Sec-WebSocket-Accept:

$accept = base64_encode(SHA1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));

而且,客户端请求中似乎不再存在Sec-WebSocket-Key1和Sec-WebSocket-Key2,而是必须从标题中提取$key:"Sec-WebSocket-Key"。

新问题:似乎即使在握手时Web套接字连接现在也可以工作,但在发送第一条消息时它会断开连接。


0
我注意到在Chrome 19的控制台中: 服务器不应该对发送给客户端的任何帧进行掩码处理。 也许这就是问题所在。一旦发送消息,它就会断开连接。在Firefox中运行良好。
我解决了这个websocket问题,现在在chrome中可以使用了。 首先我使用了:
然后我使用了来自以下链接的编码函数: https://github.com/lemmingzshadow/php-websocket 我修复了替换了编码函数,使用了lemmingzshadow的github中connection.php文件中的函数:hybi10Encode在\server\lib\WebSocket\connection.php文件中。
在函数encode中更改此参数:$masked = true为$masked = false。

-1
一个简单的解决方法是在进行握手时添加Sec-WebSocket-Accept信息,代码如下:
    list($resource,$host,$origin,$key) = $this->getheaders($buffer);

    $accept = base64_encode(SHA1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));

    $upgrade  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
            "Upgrade: WebSocket\r\n" .
            "Connection: Upgrade\r\n" .
            "WebSocket-Origin: {$origin}\r\n" .
            "WebSocket-Location: ws://{$host}{$resource}\r\n".
            "Sec-WebSocket-Accept: " . $accept . "\r\n\r\n";
    $this->handshakes[$socket_index] = true;

    socket_write($socket,$upgrade,strlen($upgrade));

在哪里,

$accept = base64_encode(SHA1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));

$key是从$buffer获取的Sec-WebSocket-Key,您可以使用print_r($buffer)查看。

希望这能解决您的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接