我正在使用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”标题中。
知道如何让它再次运作吗?
答案 0 :(得分:14)
服务器违反了WebSocket协议。 Chrome很可能只是在版本20中更正确地遵守了标准,并且揭示了服务器中的错误。
问题是服务器在响应中发送回“Sec-WebSocket-Protocol”标头,但这仅在客户端在请求中发送相同标头时才合法。如果客户端没有发送Sec-WebSocket协议,则服务器应该省略响应中的标头。
中第22页的/ subprotocol / description答案 1 :(得分: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";
答案 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)来看看。
希望这可以解决您的问题..