我用 PHP 编写了 websocket 服务器/客户端,它为我工作了 2 年。现在它不起作用,说:WebSocket 握手期间出错:不正确的“Sec-WebSocket-Accept” header 值
我的客户端代码基本上是这样的:
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);
}
有趣的是,那些人只是改变了标准,没有保持旧代码的功能,也没有在网上说任何话(我真的很努力地用谷歌搜索它)。有谁知道我的问题是什么?
最佳答案
所以我找到了问题所在。这就是缓冲区限制。
显然,变量 $buffer
仅包含大约 4 KB 的数据,并且由于来自 dataTables 的 cookie,输入数据要多得多。并且 Sec-WebSocket-Key
header 位于所有 cookie 之后。所以$key
每次都是空的,给出错误的Sec-WebSocket-Accept
。
建议:更深入地调试。
关于javascript - WebSocket握手时出错: Incorrect 'Sec-WebSocket-Accept' header value with PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29590412/