2017-09-19 26 views
0

現在、json_encodeバッファのデータをデコードし、node.js websocketサーバーでデコードしようとしています。JSONエンコードされたバッファのデータが正しくエンコードされていません

私は私にHTML形式のANSIデータを提供するドッカーコンテナを使用しています。

私はSymfony Process componentを使用して、ドッカーコンテナからのリアルタイムプロセス出力を取得し、socket_writeを使用してNode.js websocketサーバーに出力します。

Node.jsサーバーにsocket_writeとのドッキングウィンドウからのデータを書き込むための私のコードは次のようになります。私のサーバー上で

$process->run(function ($type, $buffer) use ($socket, $converter) { 
    $html = $converter->convert($buffer); 

    // Pass the room we want to send the HTML socket messages to. 
    $data = [ 
     'html' => $html, 
     'room' => 'http://arbiter.dev/stephan-v/arbiter-test' 
    ]; 

    $json = json_encode($data); 

    socket_write($socket, $json, strlen($json)); 
}); 

私はそうのようなjson_encodedデータをデコードしてみてください:

socket.on('data', (msg) => { 
    const data = JSON.parse(msg); 
    io.sockets.in(data.room).emit('log', data.html.toString().trim()); 
}); 

この構文エラーで失敗する:

SyntaxError: Unexpected token { in JSON at position 66

私はNode.jsサーバー上の着信msgconsole.logとき、私は出力としてこれを取得:

Websocket server online, listening on port :5600 
<Buffer 7b 22 68 74 6d 6c 22 3a 22 3c 73 70 61 6e 20 73 74 79 6c 65 3d 5c 22 62 61 63 6b 67 72 6f 75 6e 64 2d 63 6f 6c 6f 72 3a 20 23 30 37 33 36 34 32 3b 20 ... > 
<Buffer 7b 22 68 74 6d 6c 22 3a 22 3c 73 70 61 6e 20 73 74 79 6c 65 3d 5c 22 62 61 63 6b 67 72 6f 75 6e 64 2d 63 6f 6c 6f 72 3a 20 23 30 37 33 36 34 32 3b 20 ... > 
<Buffer 7b 22 68 74 6d 6c 22 3a 22 22 2c 22 72 6f 6f 6d 22 3a 22 68 74 74 70 3a 5c 2f 5c 2f 61 72 62 69 74 65 72 2e 64 65 76 5c 2f 73 74 65 70 68 61 6e 2d 76 ... > 
<Buffer 7b 22 68 74 6d 6c 22 3a 22 22 2c 22 72 6f 6f 6d 22 3a 22 68 74 74 70 3a 5c 2f 5c 2f 61 72 62 69 74 65 72 2e 64 65 76 5c 2f 73 74 65 70 68 61 6e 2d 76 ... > 
undefined:1 
{"html":"","room":"http:\/\/arbiter.dev\/stephan-v\/arbiter-test"}{"html":"","room":"http:\/\/arbiter.dev\/stephan-v\/arbiter-test"} 
                   ^

SyntaxError: Unexpected token { in JSON at position 66 
    at JSON.parse (<anonymous>) 

だから、msgがバッファストリームであるようだが、それでもJSON.parseは、メッセージの最初のカップルのためにそれで動作するようです。

次に約3番目のメッセージについて、私はソケットに送信していますが失敗します。ここで何が起こっているのですか?

最後のconsole.log文に2つのJSONオブジェクトが貼り付けられているので、私のメッセージは適切なものにチャンクされるべきであることを認識していませんか?

+0

ネットワークでは、データがどのようにチャンクされるかには決して依存することができません。そのため、ほとんどのプロトコルには長さインジケータがあるため、このメッセージを終了するために必要なバイト数を把握してから、次の準備ができます。 – Keith

+0

これはどのように 'websocket'の問題ですか?未処理のTCP/IPプロトコルまたはWebsocketプロトコルを使用していますか? 2つの異なること。 – Myst

+0

私の 'socket_write'は3番目の引数として文字列の長さです:' strlen($ json) 'これはどこが間違っていますか?適切な長さを計算できないのですか、限界を超えていますか? –

答えて

0

これは完全に私の問題を解決しているようだ:

Wait for socket_write to complete before writing again

問題は、私は理由を理解していないということです。私はそうのような私のJSONオブジェクトの長さを渡しsocket_writeのための私の3番目の引数として:

socket_write($socket, $json, strlen($json)); 

私はそれが単にストリームであり、それは、バッファ内のデータの「チャンク」を受け入れるので、私は長さを設定する必要があります知っていますいわば。

しかし、strlen($json)はすでにすべての問題を解決していないはずですか?

なぜ私のsocket_writeメッセージは複数のJSONオブジェクトを一緒に追加することがありますか?

編集

私が読んでいたものから、これらのソケットは、TCPで動作するため、データのチャンクがあるためNagle's Algorithmの起こるようですし、メッセージのサイズとするとき、最後のメッセージが認められているに応じて、チャンクされています。

PHPはPHP 7にTCP_NODELAYを導入しました。1しかし、アルゴリズムは理由があるので、このことに注意する必要があります。

これを修正する最良の方法は、PHPで追加した区切り文字を分割して、サーバー側でメッセージを分割することです。

私はこれについて間違っている場合は私を修正してください、私はこれについての考えを聞くのが大好きです。

関連する問題