2

私は現在、ネットクラスを使用してPHPサーバーに接続する単純なNodeJSクライアントに取り組んでいます。さらに、NodeJSクライアントは、PHPサーバーから受信したデータをSocket.IOに接続されているブラウザーに送信するSocket.IOサーバーとして機能しています。

これまでのところ、すべてが正常に機能しています。しかし、別のクライアントとSocket.IOに接続すると、PHPサーバーは接続されているすべてのクライアントに通知を送信する必要があります。したがって、JSONでエンコードされた配列をNodeJSクライアントに送信します。NodeJSクライアントはJSONデータを処理します(デコードして少し変更します)。

ここで問題となるのは、PHPサーバーによって送信された2つの別々のメッセージがNodeJSのonDataイベント処理関数で連結されることがあるということです。

client.on("data", function(data) {

   var msgData = JSON.parse(data.toString("utf8"));
   [...]
}

変数データには、次のような2つのJSON文字列が含まれることがあります(毎回ではありません!)。

 { "todo":"message", [...] } { "todo":"message", [...] }

もちろん、これにより、JSON.parse関数によって例外がスローされます。変数データが​​次のようなonData関数の2つの呼び出しを期待していました。

{ "todo":"message", [...] }

PHPサーバー側では、現在提供されているすべてのSocket.IO接続を含む配列を反復処理する必要があります。

foreach($sockets as $id => $client) {

    $nodeJS->sendData($client, array("todo" => "message", [...]);
}

$ nodeJS-> sendData -function json-配列をエンコードし、NodeJSクライアントに送信します。

socket_write($nodeClient, json_encode($dataToSend));

$ nodeJS-> sendData関数は、socket_writeと同様に、確実に2回呼び出されます。

PHPとNodeJSのどちらがこれらの2つの文字列を連結しているかわかりません。私が欲しいのは、NodeJSが$ nodeJS-> sendData関数が呼び出されるたびにonDataハンドラーを1回呼び出すことです(たとえば、sendDataが2回呼び出されます→onData-eventが2回発生します)。もちろん、jsonでエンコードされた各文字列の最後にフラグを追加し、後でonData関数でそれらを配列に分割することもできます。しかし、私はその解決策があまり好きではありません。

これを達成するためのより簡単な方法はありますか?

4

2 に答える 2

4

ソケットから読み取る場合、データは任意のチャンクになり、処理するのに意味のある単位に分割するために完全にコードに依存することを覚えておくことが重要です。各チャンクが1つの意味のあるユニットに対応するという保証はまったくありません。

yannisguは、ソリューションの最初の部分を提供しました(各ユニットを改行で終了して、コードがどこで終了するかを判断できるようにします)。次に、受信データをバッファリングしてユニットに分割する2番目の部分を実装する必要があります。

初期化時に、次のようなことを行います

var buf = '';

clientのエンコーディングをutf8に設定します。

"data"ハンドラー内:[更新:josh3736の提案を組み込んだ]

buf += data;
var idx;
while ((idx = buf.indexOf('\n')) >= 0) {
   // there's at least one complete unit buffered up
   var unit = buf.slice(0, idx);
   // extract it
   if (unit.slice(-1) == '\r') {
     // CRLF delimited
     unit = unit.slice(0, -1);
   }
   if (unit.length) {
     // ignore empty strings
     var msgData = JSON.parse(unit);
     [...]
     // process it
   }
   buf = buf.slice(idx +1);
   // discard it
}
// at this point, buf is either empty or contains an incomplete
// unit which will be processed as soon as the rest of it comes in
于 2012-08-23T00:00:41.923 に答える
1

PHP側のJSON-Stringの後に新しい行を追加してみてください。

于 2012-08-22T11:16:16.267 に答える