【问题标题】:Serverside Websocket Handshake fails with 'Sec-WebSocket-Accept mismatch'服务器端 Websocket 握手失败并出现“Sec-WebSocket-Accept mismatch”
【发布时间】:2015-01-14 13:39:52
【问题描述】:

我尝试在 PHP 中创建一个使用当前 WebSocket 协议 13 的 Websocket 服务器。

我根据 RFC 实现了标头创建,但在 Google Chrome(版本 31)中它仍然失败,并显示错误消息 Error during WebSocket handshake: Sec-WebSocket-Accept mismatch。 Firefox 至少显示响应,但它也不会触发客户端 onOpen 事件。

下面是 PHP 中的最小测试服务器,其中包含我用来创建标头的代码:

<?php

$srv = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($srv, '0.0.0.0', 50500);
socket_listen($srv, 10);

for(;;){

    $sock = socket_accept($srv);

    // get header
    $header = socket_read($sock, 1024);

    // extract key
    $keys = array();
    preg_match_all("/Sec-WebSocket-Key:\s*(.*)\s*/", $header, $keys);

    if(count($keys) < 1){
         // Not a valid Websocket Handshake
         socket_close($sock);
         continue;
    }

   // create hash according to RFC
   $key = $keys[1][0];
   $accept = base64_encode(SHA1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));

   // create header
   $h = "HTTP/1.1 101 Switching Protocols\r\n";
   $h .= "Upgrade: websocket\r\n";
   $h .= "Connection: Upgrade\r\n";
   $h .= "Sec-WebSocket-Accept: $accept\r\n";
   $h .= "Sec-WebSocket-Protocol: 13\r\n\r\n";

   echo $h;

   // send header to client
   socket_write($sock,$h,strlen($h));

}

?>

我在这里遗漏了什么吗?

提前致谢!

【问题讨论】:

    标签: php google-chrome websocket


    【解决方案1】:

    正则表达式/Sec-WebSocket-Key:\s*(.*)\s*/ 将在匹配的内容中包含\r 字符(. 匹配\r 但不匹配\n),因此您的$key 变量将具有错误的值。您需要找出一个匹配所有内容的正则表达式,但末尾的 \r\n 序列除外。

    此外,如果客户端在请求中包含Sec-WebSocket-Protocol 属性,则服务器应仅包含它,并且该值必须是客户端Sec-WebSocket-Protocol 属性中请求的协议之一。否则客户端会报错,见RFC 6455。

    【讨论】:

    • 感谢您的建议,您是对的。我将正则表达式更改为/Sec-WebSocket-Key:\s*(.*?)\r\n/,但不幸的是它仍然不起作用。在 Firefox(第 26 版)中,onOpen 事件现在会触发,但在 Chrome 中仍然不会......
    • @lkdl 我使用更新的正则表达式尝试了服务器,使用 websocket.org/echo.html 作为客户端(和 chrome 32)。我没有收到接受字段的错误。但它抱怨Sec-WebSocket-Protocol 标头,客户端没有在请求中发送它,所以它不应该在响应中。删除它,握手将成功。 (删除协议行时不要忘记调整尾随\r\n)。
    • 现在它也适用于我发布的示例和更改的正则表达式,非常感谢您的努力!猜猜我以某种方式搞砸了所有的测试......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 2015-06-17
    • 2016-06-28
    • 2011-12-26
    相关资源
    最近更新 更多