PHP中的简单websocket服务器

Mar*_*rov 15 php websocket phpwebsocket

我正在用PHP开发一个简单的websocket服务器.我知道有很多现有的实现,但我想自己做,以便更好地学习协议.我设法做握手罚款,我的客户连接到服务器.我还设法解码来自客户端的数据,但我发送回消息时遇到问题.客户端收到我的响应后会断开连接.Firefox说The connection to ws://localhost:12345/ was interrupted while the page was loading..

我用这个答案作为指导.

这是我的数据包装代码:

private function wrap($msg = ""){
    $length = strlen($msg);
    $this->log("wrapping (" . $length . " bytes): " . $msg);

    $bytesFormatted = chr(129);
    if($length <= 125){
        $bytesFormatted .= chr($length);
    } else if($length >= 126 && $length <= 65535) {
        $bytesFormatted .= chr(126);
        $bytesFormatted .= chr(( $length  >> 8 ) & 255);
        $bytesFormatted .= chr(( $length       ) & 255);
    } else {
        $bytesFormatted .= chr(127);
        $bytesFormatted .= chr(( $length >> 56 ) & 255);
        $bytesFormatted .= chr(( $length >> 48 ) & 255);
        $bytesFormatted .= chr(( $length >> 40 ) & 255);
        $bytesFormatted .= chr(( $length >> 32 ) & 255);
        $bytesFormatted .= chr(( $length >> 24 ) & 255);
        $bytesFormatted .= chr(( $length >> 16 ) & 255);
        $bytesFormatted .= chr(( $length >>  8 ) & 255);
        $bytesFormatted .= chr(( $length       ) & 255);
    }

    $bytesFormatted .= $msg;
    $this->log("wrapped (" . strlen($bytesFormatted) . " bytes): " . $bytesFormatted);
    return $bytesFormatted;
}
Run Code Online (Sandbox Code Playgroud)

更新:我尝试使用Chrome,我在控制台中打印出以下错误:A server must not mask any frames that it sends to the client.

我在服务器上放了一些控制台打印输出.它是一个基本的echo服务器.我试着用aaaa.所以实际包装的消息必须是6个字节.对?

在此输入图像描述

Chrome会打印出上述错误.还要注意,在包装消息后,我只需将其写入套接字:

$sent = socket_write($client, $bytesFormatted, strlen($bytesFormatted));
$this->say("! " . $sent);
Run Code Online (Sandbox Code Playgroud)

它打印6意味着6个字节实际写入线.

如果我尝试使用aaa,Chrome不会打印错误,但也不会调用我的onmessage处理程序.它挂起就好像在等待更多数据一样.

任何帮助高度赞赏.谢谢.

小智 4

我遇到了同样的问题:对于从服务器发送的某些消息,浏​​览器中没有响应,对于某些消息,显示错误“服务器不得屏蔽任何帧...”,尽管我没有添加任何屏蔽。原因在于发送的握手。握手的内容是:

"HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
...
"WebSocket-Location: ws://{$host}{$resource}\r\n\r\n" . chr(0)
Run Code Online (Sandbox Code Playgroud)

chr(0) 就是原因,在我删除它之后一切正常。