Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
20
rated 0 times [  22] [ 2]  / answers: 1 / hits: 18753  / 13 Years ago, tue, may 10, 2011, 12:00:00

I have two node processes that speak to each other. I will call them [Node Server] and [Node Sender]. [Node Sender] continually processes information and writes a message over a TCP connection to [Node Server]. [Node Server] then writes back a status message.



Example of [Node Sender]:



var message = Test Message;
[Node Sender].connection.write(message);


Example of [Node Server]:



[Node Server].socket.on(data, function(p_data) {
this.write(OK);

// Do some work with p_data
}


This works without issue, p_data always contains Test Message when sent at anything above 5 milliseconds. However, if I speed [Node Sender] to write every millisecond, p_data occasionally ends up with something like Test MessageTest MessageTes.



I understand that the buffer in [Node Sender] is probably filling faster than the write command is sending it. Is there a way to force a one-to-one ratio in sending messages while still remaining asynchronous?



I can certainly just add a terminator to my message and just fill a buffer in [Node Server], but I wanted to make sure there wasn't something obvious I was missing.


More From » tcp

 Answers
10

No, you're not missing anything and yes, you do need to add some form of termination to your messages.



There are two basic problems here:




  1. The TCP protocol is stream-oriented, not message-oriented; it has no intrinsic knowledge of what might constitute a message.


  2. The data event fired by the node.js net library indicates that some data has arrived but without any idea of what a message might contain, it cannot indicate that it has received any specific data.




So by sending your messages faster than Node can process them, the socket recv buffer fills with multiple messages.



A typical solution to this problem is to add line-termination, as can be found in
https://github.com/baudehlo/Haraka/blob/master/connection.js at lines 32-34:



self.client.on('data', function (data) {
self.process_data(data);
});


and lines 110-134:



Connection.prototype.process_data = function (data) {
if (this.disconnected) {
logger.logwarn(data after disconnect from + this.remote_ip);
return;
}

this.current_data += data;
this._process_data();
};

Connection.prototype._process_data = function() {
var results;
while (results = line_regexp.exec(this.current_data)) {
var this_line = results[1];
if (this.state === 'pause') {
this.early_talker = 1;
var self = this;
// If you talk early, we're going to give you a delay
setTimeout(function() { self._process_data() }, this.early_talker_delay);
break;
}
this.current_data = this.current_data.slice(this_line.length);
this.process_line(this_line);
}
};

[#92302] Monday, May 9, 2011, 13 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
estefanib

Total Points: 508
Total Questions: 104
Total Answers: 83

Location: Lebanon
Member since Sun, Aug 2, 2020
4 Years ago
;