5

我正在使用 lemmingzshadow ( web ) 的 PHP Websocket 服务器。到目前为止,一切都很好。

更新到 chrome 20 后,如果我想与服务器握手,则会出现此错误

Error during WebSocket handshake: Sec-WebSocket-Protocol mismatch 

来自 chrome 20 的标题

GET /demo HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: gomokulive.eu:8001
Origin: http://www.gomokulive.eu
Sec-WebSocket-Key: s+AMQQu4Q10xH2AKy49byg==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame

发回的标头:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: dMCVYKkF5VRrIouWFW7EYdvfD28=
Sec-WebSocket-Protocol: demo

我认为问题在于 Chrome 20 中的“Sec-WebSocket-Extensions: x-webkit-deflate-frame”标头。

知道如何让它再次工作吗?

4

3 回答 3

15

服务器违反了 WebSocket 协议。Chrome 很可能只是在版本 20 中更正确地遵守了该标准,这暴露了服务器中的一个错误。

问题是服务器在响应中发回了“Sec-WebSocket-Protocol”标头,但这只有在客户端在请求中发送相同的标头时才合法。如果客户端不发送 Sec-WebSocket-Protocol,那么服务器应该在响应中省略标头。

请参阅rfc6455 第 4.2.2 节中第 22 页的 /subprotocol/ 描述

于 2012-07-02T21:02:34.563 回答
3

php-websocket的快速修复方法是:

$response.= "Sec-WebSocket-Accept: " . $secAccept . "\r\n";
if (isset($headers['Sec-WebSocket-Protocol']))
{
    $response.= "Sec-WebSocket-Protocol: " . substr($path, 1) . "\r\n";
}
$response .= "\r\n";
于 2012-07-30T00:30:19.760 回答
1

一个简单的解决方法是Sec-WebSocket-Accept在do_handshake时添加信息,代码如下:

    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 是Sec-WebSocket-Key从 $buffer 得到的,你可以 print_r($buffer) 看看。

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

于 2013-03-06T17:57:31.467 回答