3

問題は、大きなシリアル化された JSON (16,000 文字を超える) をネット ソケット経由で送信するとチャンクに分割されることです。各チャンクはdata、受信側でイベントを発生させます。JSON.parse()そのため、受信データを単純に実行すると、 で失敗する場合がありSyntaxError: Unexpected end of inputます。

これまでに思いついた回避策'\u0000'は、シリアル化された JSON の末尾に null 文字 ( ) を追加し、受信側でそれを確認することです。次に例を示します。

var partialData = '';
client.on( 'data', function( data ) {
    data = data.toString();
    if ( data.charCodeAt( data.length - 1 ) !== 0 ) {
        partialData += data;
        // if data is incomplete then no need to proceed
        return;
    } else {
        // append all but the null character to the existing partial data
        partialData += data.substr( 0, data.length - 1 );
    }
    // pass parsed data to some function for processing
    workWithData( JSON.parse( partialData ));
    // reset partialData for next data transfer
    partialData = '';
});

このモデルの失敗の 1 つは、レシーバーが複数のソケットに接続されていて、各ソケットが大きな JSON ファイルを送信している場合です。

これを行う理由は、同じボックスで実行されている 2 つのプロセス間でデータを渡す必要があり、ポートを使用したくないからです。したがって、ネットソケットを使用します。したがって、2 つの質問があります。まず、2 つの Node.js プロセス間で大きな JSON データをすばやく渡すためのより良い方法はありますか? 次に、これが最善の方法である場合、シリアル化された JSON が送信時にチャンクに分割される場合、どのようにすればより適切に処理できるでしょうか?

4

2 に答える 2

4
  1. 毎回try...catchを使用して、それが有効なjsonであるかどうかを確認できます。ただし、パフォーマンスはあまり良くありません。
  2. 送信側でjsonのサイズを計算し、JSONの前に送信できます。
  3. JSONにはありそうもない境界文字列を追加できます。あなたの\u0000-はい、それは合法的な方法のようです。しかし、最も人気のある選択肢は改行です。

  4. dnodeのような外部ライブラリを使用できます。これは、前に説明したことをすでに実行しているはずです。それを試してみることをお勧めします。本当に。

このモデルの失敗の1つは、レシーバーが複数のソケットに接続されており、各ソケットが大きなJSONファイルを送信している場合です。

ソケットごとに異なるバッファを使用します。ここでは問題ありません。

于 2012-05-09T05:56:12.723 に答える
1

各ソケットを個別に識別し、それぞれのバッファを構築することができます。接続を受信すると各ソケットに ID を追加し、データを受信するとそのデータをバッファに追加します。

net.createServer( function(socket) {
  // There are many ways to assign an id, this is just an example.
  socket.id = Math.random() * 1000;
  socket.on('data', function(data) {
    // 'this' refers to the socket calling this callback.
    buffers[this.id] += data;
  });
});

バッファーを使用する準備ができていることを示す「キー」区切り文字を受け取ったかどうかを毎回確認できます。

于 2013-11-11T22:59:26.053 に答える