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 ハンドラも呼び出しません。追加のデータを待っているかのようにハングします。
どんな助けでも大歓迎です。ありがとう。