2016-08-08 4 views
0

Windowsアプリケーションから大きなJSON文字列を受け取る必要があります。しかし、接続を閉じる前にデータが完全に送信されるのを待つ必要があるかどうかはわからないようです。net.socketのデータが完全に送信されるまで待つ方法

私はコールバックを待つ必要があることを読みました。私はdocumentationを見てきました。私はその周りを頭で囲むことができません。

私はNode.jsとJavascriptプログラミングには一般的なので、ここで私に同行してください。

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

    completeData = data; 
    //Close the connection 
    client.end(); 
}); 
client.on('end', function() { 
    //Parse the data after receiving full json 
    responseData = JSON.parse(completeData); 
    console.log('Received data \r\n' + JSON.stringify(responseData, null, 4)); 
    client.destroy(); 
    console.log('Connection closed'); 
    next(); 
}); 

EDIT:

私はこれを試してみたが、私はすべてのデータを取得する前に、それはまだそれを閉じています。

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

if (newlineRegex.test(data)) { 
    console.log('Received: ' + data); 
    responseData = JSON.parse(data); 
    console.log('Received data \r\n' + JSON.stringify(responseData, null, 4)); 
    client.end(); 
} 

});

編集:完全なコードを追加すると、私は何かが欠けているに違いありません。 私がそれをまったく解析しないと、JSON.parseを高速で実行するコードをクライアントに追加すると(クライアントの最後には終わりません)

var keystone = require('keystone'); 
var ServerConnection = require('server-connection') 
var newlineRegex = require('newline-regex'); 

exports = module.exports = function (req, res) { 

var view = new keystone.View(req, res); 
var locals = res.locals; 

// locals.section is used to set the currently selected 
// item in the header navigation. 
locals.section = 'server'; 
locals.responseData = new Object; 
var completeData; 

var net = require('net'); 
var client = new net.Socket('null', true); 
client.connect(3333, '192.168.56.1', function (err) { 
    console.log('Connected'); 
    //String test 
    var string = '{"method":"getSerialisedDeviceInfo","params":[],"id":1}\r\n'; 
    client.write(string); 
}); 
client.on('data', function (data) { 
    completeData = completeData + data; 
    console.log(completeData); 
    //Doesn't work 
    //if (newlineRegex.test(completeData)) { 
     //client.end(); 
    //} 
}); 

client.on('end', function() { 
    //Parse the data after receiving full json 
    responseData = JSON.parse(completeData); 
    console.log('Received data \r\n' + JSON.stringify(responseData, null, 4)); 
    client.end(); 
    console.log('Connection closed'); 
    view.render('server'); 
}); 

}; 
+1

あなたが受け取るデータのすべてのチャンクに対して 'data'が起動されるので、あなたは' data'イベントで 'end'接続を行うべきではありません。 –

+0

私はデータを受け取った後で接続を閉じる必要があるので、どうすればいいですか? – Kerel

+0

接続を閉じる必要がありますが、すべてのデータを受信した後です。そして、それは 'client.on( 'end'、function(){})で起こるはずです。 –

答えて

0

TCP接続がストリームであるため、「メッセージ」の終わりを判断するために何らかの種類の確立されたプロトコルが必要です。たとえば、UDPパケットのように、組み込みの「メッセージ」境界はありません。

JSONの場合、この問題の一般的で簡単な解決策は、改行で区切られたJSON文字列を使用することです。そうすれば、改行を見るまでデータをバッファリングするだけで、JSONメッセージの終わりに達したことを知っているので、その時点で安全に解析できます。

+0

これはどのように達成できますか?上記のコードを追加しようとしました。編集を参照してください。 – Kerel

+0

改行を区切る解決策が機能するには、相手側は書式設定された/「かわいい」JSONを送信してはいけません。 – mscdex

+0

それはちょうど文字列を送信するので、データが正しくフォーマットされているかどうかを調べるために文字列化します。 [Json](http://pastebin.com/3TKwR6MK) – Kerel

0

次のコードが有効です。それが動作しない場合、私に知らせてください。

client.on('data', function(data) { 
    //Parse the data after receiving full json 
    responseData = JSON.parse(data); 
    console.log('Received data \r\n' + JSON.stringify(responseData,null,4)); 

    client.destroy(); 
    console.log('Connection closed'); 
    next(); 
}); 

client.on('error', function(){ 
    console.log('error happened'); 
}); 
+0

私は決してclient.on( 'end')コードをこのように入力しません。 net.socketはリスニングを継続します。 – Kerel

+0

client.on( 'end')で 'client.destroy()'を使用することができます –

+0

client.on( 'end')のコードは実行されません。どうしてか分かりません。 – Kerel

関連する問題