2012-07-02 3 views
4

Я использую сервер PHP Websocket от lemmingzshadow (web). До сих пор все работало отлично.Chrome 20 websocket handshake

После обновления хрома 20, если я хочу сделать рукопожатие с сервером заканчивается с этой ошибкой

Error during WebSocket handshake: Sec-WebSocket-Protocol mismatch 

заголовками из хрома 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 

Я думаю, проблема связана с заголовком «Sec-WebSocket-Extensions: x-webkit-deflate-frame» из Chrome 20.

Любая идея, как заставить его работать снова?

+0

Там, как представляется, проблема с Chrome 20 WebSockets со вчерашнего обновления, в первую очередь на платформе Windows, ... вернуться к предыдущей версии, если вы можете, или Google будет почти конечно, выпустить патч довольно быстро, потому что он предотвращает доступ к обоим профилям –

+0

У меня есть игра, которая работает на веб-сайтах, поэтому ничего не значит «вернуться к версии previus». Если ws клиент не может подключиться, пользователи будут видеть только сообщение об ошибке:/На данный момент я вернулся к реализации Flash https://github.com/gimite/web-socket-js – m4recek

+0

@MarkBaker любую новую информацию об этом? ошибка или функция? спасибо –

ответ

14

Сервер нарушает протокол WebSocket. Вполне вероятно, что Chrome просто придерживается стандарта более корректно в версии 20 и обнаруживает ошибку на сервере.

Проблема заключается в том, что сервер отсылает в ответ заголовок «Sec-WebSocket-Protocol», но это разрешено только в том случае, если клиент отправляет в запросе тот же заголовок. Если клиент не отправляет Sec-WebSocket-Protocol, сервер должен опустить заголовок в ответе.

См/подпротоколов/описание на странице 22 в Section 4.2.2 of rfc6455

+1

Кажется, вы попали в точку :) Я буду проверять его более внимательно tomorow – m4recek

+1

@kanaka upvote для 10k :) –

+0

@webarto, хе, спасибо! – kanaka

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"; 
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 is Sec-WebSocket-Key Получено из буфера $, вы можете напечатать_r ($ buffer), чтобы посмотреть.

Надеется, что это может решить вашу проблему ..

+0

, откуда берется значение 258EAFA5-E914-47DA-95CA-C5AB0DC85B11? – Ash

+1

Интересно, это фиксированный пост, попробуйте. Я точно не помню, как это было год назад. – navins

Смежные вопросы