Chrome 17中缺少“Sec-WebSocket-Accept”标题

时间:2012-02-20 07:23:39

标签: google-chrome websocket phpwebsocket

修改 我试过这个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'标头丢失

我在我的WAMP localhost上的Chrome 17.0.963.56中尝试启用了php_sockets扩展程序。

我在某处看到Chrome已经改变了它所支持的内容,但它没有深入探讨如何修复它。我希望有人能指引我。 (我是websockets的新手。)

服务器:

  

{PATH}> php startDaemon.php

     

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

     

2012-02-20 07:02:51系统:Socket绑定到localhost:8000。

     

2012-02-20 07:02:51系统:开始收听Socket。

     

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(已关闭)

3 个答案:

答案 0 :(得分:1)

我遇到同样的问题(我似乎无法在此发表评论,所以我发布了回复)。

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

在safari 5.1.4上,它运行得很好。

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

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

所以,在websocket.class.php中,我添加到server返回的头文件中:

$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,但我找不到它...感谢您的帮助!

编辑:这似乎是解决方案(对我来说至少):将参数true添加到SHA1函数中,如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套接字连接现在可以在握手上运行,它也会在发送第一条消息时断开连接。

答案 1 :(得分:0)

我注意到在Chrome 19的控制台中: 服务器不得屏蔽它发送给客户端的任何帧。 也许这就是问题所在。一旦发送消息,它就会断开连接。它在Firefox中运行良好。

我修复了这个websocket问题,现在它在chrome中运行。 我首先使用:

然后我使用了编码功能: https://github.com/lemmingzshadow/php-websocket

我修复了用lemmingzshadow的github中的connection.php文件中的一个替换了编码函数,它开始工作了。该函数名为:\ server \ lib \ WebSocket \ connection.php文件中的hybi10Encode。

在函数encode中更改此参数:$ masked = true to $ masked = false

答案 2 :(得分:-1)

一种简单的修复方法是在do_handshake时添加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是$ {1}}来自$ buffer,你可以print_r($ buffer)来看看。

希望这可以解决您的问题..