我正在用 PHP 开发一个简单的 websocket 服务器。我知道有很多现有的实现,但我想自己做,以便更好地学习协议。我设法很好地握手,我的客户连接到服务器。我还设法解码了来自客户端的数据,但我在发回消息时遇到了问题。客户端收到我的回复后断开连接。火狐说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;
}
更新:我用 Chrome 尝试过,我得到了以下错误,打印在控制台中:A server must not mask any frames that it sends to the client.
我在服务器上放了一些控制台打印输出。它是一个基本的回声服务器。我尝试使用aaaa
. 所以实际包装的消息必须是 6 个字节。对?
Chrome 打印出上述错误。另请注意,包装消息后,我只需将其写入套接字:
$sent = socket_write($client, $bytesFormatted, strlen($bytesFormatted));
$this->say("! " . $sent);
它打印 6 表示实际将 6 个字节写入线路。
如果我尝试使用aaa
,Chrome 不会打印错误,但也不会调用我的 onmessage 处理程序。它挂起,好像在等待更多数据。
任何帮助高度赞赏。谢谢。