【问题标题】:Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value with PHPWebSocket 握手期间出错:PHP 的“Sec-WebSocket-Accept”标头值不正确
【发布时间】:2015-06-17 21:11:49
【问题描述】:

我已经用 PHP 编写了 websocket 服务器/客户端,它在 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);
}

有趣的是,这些人只是更改了标准,却没有保持旧代码正常运行,也没有在网上说任何话(我真的很努力地用谷歌搜索它)。有谁知道我的问题是什么?

【问题讨论】:

  • 您好,使用不同的浏览器会失败吗?很明显的问题,但你没有具体说明。
  • @pietro909 Chrome 41 失败,Firefox 说:“Firefox 无法在 ws://192.168.1.34:38848/operator/modules/campaign/event_server.php 建立与服务器的连接"
  • @pietro909 MacOS 10.9 下的 Safari 说:“[错误] WebSocket 连接到 'ws://192.168.1.34:38848/operator/modules/campaign/event_server.php' 失败:无效的 UTF-8标头值中的序列(campaign.php,第 0 行)"
  • IE 11 似乎可以工作...

标签: javascript php websocket handshake


【解决方案1】:

所以我发现了问题所在。这就是缓冲区限制

显然,变量$buffer 仅包含大约 4 KB 的数据,并且由于来自 dataTables 的 cookie,输入数据要多得多。 Sec-WebSocket-Key 标头毕竟是 cookie。所以$key每次都是空的,给错了Sec-WebSocket-Accept

建议:更深入地调试

【讨论】:

  • 我正在使用 substr 来获取 Sec-WebSocket-Key,但是,好吧......我仍然遇到同样的错误。你能帮助我吗? :(
猜你喜欢
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多