Я кодировал сервер / клиент websocket с PHP, и он работал для меня в течение 2 лет. Теперь он не работает, говоря: Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value
Мой клиентский код по существу таков:
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). Кто-нибудь знает, в чем моя проблема?
Поэтому я понял проблему. И это был буферный предел .
По-видимому, переменная $buffer
содержала только около 4 КБ данных, а из-за файлов cookie, которые поступали из dataTables, входные данные были намного больше. И заголовок Sec-WebSocket-Key
был после всех файлов cookie. Таким образом, $key
был пустым каждый раз, предоставляя неверный Sec-WebSocket-Accept
.
Совет: отлаживать более глубоко .