Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I frame messages for sending over TCP with node.js?

Tags:

json

node.js

tcp

I need to send a JSON string to a number of TCP clients from a node.js TCP server.

In order to read the messages from the socket/stream on the client side I need to do some sort of message framing. One way to do this is to prefix the message with the length of the message as an array - then convert that to the buffer size for the message on the client side.

How would I do something like this in node.js/javascript on the server and then read it out on the client side using a .NET client?

Given this client side code, how would I frame the message correctly on the server side using javascript/node?

TcpClient client = new TcpClient(server, port);
var netStream = client.GetStream();

// read the length of the message from the first 4 bytes
byte[] b = new byte[4];
netStream.Read(b, 0, b.Length);
int messageLength = BitConverter.ToInt32(b, 0);

// knowing the length, read the rest of the message
byte[] buffer = new byte[messageLength];
netStream.Read(buffer, b.Length, buffer.Length);
var message = System.Text.Encoding.UTF8.GetString(buffer);
like image 705
alex.tashev Avatar asked Jul 11 '11 12:07

alex.tashev


2 Answers

to unframe incoming data in nodejs you can try to use node-bufferlist or node-buffers or create your own FSM manually and feed it with incoming chunks of data

server side is simplier:

function sendPacket(stream, buffer)
{
    var prefix = new Buffer(4);
    var length = buffer.length;
    var offset = 0;
    // serialize 32bit little endian unsigned int
    prefix[offset++] = length & 0xff;
    prefix[offset++] = (length >> 8)  & 0xff );
    prefix[offset++] = (length >> 16)  & 0xff );
    prefix[offset++] = (length >> 24)  & 0xff );
    stream.write(prefix);
    stream.write(buffer);
}

or you can use node v0.5+ buffer.writeUInt32

like image 171
Andrey Sidorov Avatar answered Oct 11 '22 23:10

Andrey Sidorov


You can use frame-stream:

var net = require('net')
var frame = require('frame-stream')
var port = 30000

net.createServer(function(socket) {
  socket.pipe(frame.decode()).on('data', function(buf) {
    console.log(buf.toString())
  })
}).listen(port, function() {
  net.connect(port, function() {
    var encode = frame.encode()
    encode.pipe(this)
    encode.write('hello world')
    encode.end('cheerio!')
  })
})
like image 22
Bernardo Ramos Avatar answered Oct 11 '22 22:10

Bernardo Ramos