我正在使用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;
}
更新:我尝试了使用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处理程序。 它就像在等待更多数据一样挂起。
非常感谢任何帮助。谢谢。
chr(129)
返回一个字节。pack('c', 129)
也返回一个字节。请参见 http://codepad.org/N3KWIXTq - Martin Dimitrovsocket_write
写入数据。它的返回值告诉我所有字节都已正确发送到客户端。 - Martin Dimitrov