Javascript 为WebSocket[握手]创建一个PHP套接字服务器

Javascript 为WebSocket[握手]创建一个PHP套接字服务器,javascript,php,html,sockets,websocket,Javascript,Php,Html,Sockets,Websocket,为了使用HTML5 WebSocket API,我尝试创建自己的PHP socket服务器,但我无法执行握手步骤,我阅读了下面的PHP服务器代码: 下面是Javascript代码: var socket = new WebSocket("ws://127.0.0.1:1577/server.php"); socket.onopen = function (e) { console.log("openned : "+e.readyState); } socket.onclose = fu

为了使用HTML5 WebSocket API,我尝试创建自己的PHP socket服务器,但我无法执行握手步骤,我阅读了下面的PHP服务器代码:

下面是Javascript代码:

var socket = new WebSocket("ws://127.0.0.1:1577/server.php");

socket.onopen = function (e) {
    console.log("openned : "+e.readyState);
}
socket.onclose = function (e) {
    console.log("Socket connection closed : "+e);
}
下面是PHP代码:

<?php

set_time_limit(0);
$adr = "127.0.0.1";
$port = 1577;

$m_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$msg = "Welcome...";
$cls = array();

socket_bind($m_sock, $adr, $port);
socket_listen($m_sock, 5);
echo "Server start...\n\n";

do{
        $msgsock = socket_accept($m_sock);

        array_push($cls, $msgsock);
        echo "Connected...\n\n";
        usleep(100);
        //socket_write($msgsock, $msg, strlen($msg)); //this is the 'bug'
        do{
                if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
                   echo "socket_read() fail :" . socket_strerror(socket_last_error($msgsock)) . "\n";
                    break 2;
                }
                if(preg_match("/Sec-WebSocket-Key: (.*)/",$buf,$match)){ 
                        $key =  base64_encode(hash("sha1",trim($match[1])."258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); 
                        $response_header =    "HTTP/1.1 101 Switching Protocols"."\r\n".
                        "Upgrade: websocket"."\r\n".
                        "Connection: Upgrade"."\r\n".
                        "Sec-WebSocket-Accept: $key"."\r\n\r\n";

                        //SERVER RESPONSE ----
                        socket_write($msgsock,$response_header,strlen($response_header));

                        echo "handshake done...";
                };
        } while(1);
        socket_close($msgsock);
} while(1);
下面是PHP服务器生成的响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: MDQ1NjFhMzc1YjY5MWQwNTU1ZGIzNDYyZmM0YTc1ODFhMDBlMzdmOQ==

您可以阅读的源代码,看看他们是如何做到的


有一个类实现了握手。

仅通过查看响应,您的websocket accept看起来是错误的,看起来太长了。我知道这一点,因为我有完全相同的问题。如果这是我遇到的同一个问题,那么问题是:

SHA-1传回一个十六进制值。此值不能按原样简单地转换为base64。必须首先将十六进制值转换为ascii文本,然后才能对ascii文本值进行base64编码


这里的简单答案是简单地获取从SHA-1传回的十六进制值,并将其分成两个字符的块。取这两个字符,将它们转换为正常的十进制数,然后查找该数字对应的ascii字符代码。

只需在哈希函数调用中添加第三个参数“true”。所以看起来是这样的:

hash("sha1",trim($match[1])."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true)

有关更多信息,请粘贴您收到的请求和发送的响应。我在此处添加Javascript代码(请求)和php代码中已有的响应=>socket_write($msgsock,$response_header,strlen($response_header));不,我指的是实际的HTTP请求和您的代码生成的HTTP响应。谢谢您。我最终发现错误是在第二个循环之前编写的套接字(我更正了代码:)与您的答案一致,但如果您感兴趣,我最终找到了解决方案:整个代码:)
hash("sha1",trim($match[1])."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true)