2015-04-12 2 views
2

Я кодировал сервер/клиент websocket с PHP, и он работал для меня в течение 2 лет. Сейчас он не работает, говоря: Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header valueОшибка во время рукопожатия WebSocket: неверное значение заголовка «Sec-WebSocket-Accept» с PHP

Мой клиентской код, по существу, это:

socket = new WebSocket("ws://<?= EVENT_SERVER_ADDR ?>:"+EVENT_SERVER_PORT+"<?= EVENT_SERVER_WWW_PATH ?>"); 

код PHP серверный это:

list ($resource, $host, $connection, $version, $origin, $key, $protocol, $upgrade) = $this->getheaders ($buffer); 

$this->log ("Handshaking..."); 
$reply = 
    "HTTP/1.1 101 Switching Protocols\r\n" . 
    "Upgrade: {$upgrade}\r\n" . 
    "Connection: {$connection}\r\n" . 
    "Sec-WebSocket-Version: {$version}\r\n" . 
    "Sec-WebSocket-Origin: {$origin}\r\n" . 
    "Sec-WebSocket-Location: ws://{$host}{$resource}\r\n" . 
    "Sec-WebSocket-Accept: " . $this->calcKey ($key) . "\r\n"; 
if ($protocol) 
    $reply .= "Sec-WebSocket-Protocol: $protocol\r\n"; 
$reply .= "\r\n"; 

// Closes the handshake 
socket_write ($user->socket, $reply, strlen ($reply)); 

function calcKey ($key) { 
    // Constant string as specified in the ietf-hybi-17 draft 
    $key .= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 
    $key = sha1 ($key, true); 
    // $key = pack ('H*', $key); // should I uncomment this line? 
    $key = base64_encode ($key); 

    return $key; 
} 

function getheaders ($buffer) { 
    $resource = $host = $connection = $version = $origin = $key = $protocol = $upgrade = null; 

    preg_match ('#GET (.*?) HTTP#', $buffer, $match) && $resource = $match[1]; 
    preg_match ("#Host: (.*?)\r\n#", $buffer, $match) && $host = $match[1]; 
    preg_match ("#Connection: (.*?)\r\n#", $buffer, $match) && $connection = $match[1]; 
    preg_match ("#Sec-WebSocket-Version: (.*?)\r\n#", $buffer, $match) && $version = $match[1]; 
    preg_match ("#Origin: (.*?)\r\n#", $buffer, $match) && $origin = $match[1]; 
    preg_match ("#Sec-WebSocket-Key:\s*(.*?)\r\n#", $buffer, $match) && $key = $match[1]; 
    preg_match ("#Sec-WebSocket-Protocol:\s*(.*?)\r\n#", $buffer, $match) && $protocol = $match[1]; 
    preg_match ("#Upgrade: (.*?)\r\n#", $buffer, $match) && $upgrade = $match[1]; 

    return array ($resource, $host, $connection, $version, $origin, $key, $protocol, $upgrade); 
} 

Забавно, что эти ребята просто изменили стандарт без сохраняя старый код и не говоря ни слова в Интернете (я действительно очень старался google). Кто-нибудь знает, в чем моя проблема?

+0

Привет, он не работает с разными браузерами? Очевидный вопрос, но вы не указали его. – pietro909

+0

@ pietro909 не работает с Chrome 41, Firefox говорит: «Firefox не может установить соединение с сервером по адресу ws: //192.168.1.34: 38848/operator/modules/campaign/event_server.php» –

+0

@ pietro909 Safari под MacOS 10.9 говорит: «[Ошибка] Соединение с WebSocket с« ws: //192.168.1.34: 38848/operator/modules/campaign/event_server.php »не выполнено: недопустимая последовательность UTF-8 в значении заголовка (campaign.php, line 0)» –

ответ

4

Итак, я понял проблему. И это был буферный лимит.

По-видимому, переменная $buffer содержала только около 4 КБ данных, и из-за куки-файлов, которые поступали из dataTables, входные данные были намного больше. И заголовок Sec-WebSocket-Key был после всех файлов cookie. Таким образом, $key был пуст каждый раз, давая неправильный Sec-WebSocket-Accept.

Совет: отладка более глубоко.

+0

Я использую substr для получения 'Sec-WebSocket-Key', но, ну ... я все равно получаю ту же ошибку. Вы можете мне помочь? :( – Hydro

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