socket.emit in a simple TCP Server written in NodeJS?

Problem

[as you’ll see, I don’t understand the basic concepts of a TCP server and client very well and probably socket.emit is not even possible, but I’d like to know the best alternative or similar thing…]

Socket.io has a beautiful thing to emit events and catch them on the other side, it’s in it’s first page (http://socket.io). Can I do something similar like that but with NodeJS’ regular ‘net’ module ? If not then what’s the equivalent ?

I tried:

server.js

var server = net.createServer(function(socket) {
socket.on("connect",function() {
socket.emit('test',{msg : 'did you get it ?'});
});
}).listen(8000);

client.js

var client = net.createConnection(8000, localhost);
client.on('connect',function(){
client.on('test',function(data) {
console.log(data.toString());
});
});

But as you can imagine, it does not work. How can I achieve this ?

Thanks in advance.

Problem courtesy of: João Pinto Jerónimo

Solution

Well, net is just an interface to TCP. To send and receive messages you need to design and implement your own protocol on top of TCP. TCP is a stream-oriented protocol and not message-oriented. This means that you must invent a way for the reader to separate messages. The simplest way to separate messages are to insert \n characters between them. The simplest way to encode messages as a byte stream is to use JSON.stringify. So:

client.js

var Lazy = require('lazy'), net = require('net')

var client = net.createConnection(8000)

new Lazy(client).lines.forEach(function (msg)
{
console.log(JSON.parse(msg))
})

server.js

var net = require('net')

var server = net.createServer(function(socket) {
socket.on("connect",function() {
var str = JSON.stringify({foo : 'test', msg : 'did you get it ?'}) + "\n"
socket.write(str)
});
}).listen(8000);

You can start from this and elaborate. For example, you can use EventEmitter library class on receiver side and emit different events upon receiving different messages.

The ‘lazy’ module is available on NPM and is used to split the receiving byte stream into separate lines. The splitting is doable by hand, but it will require like 20 more lines of code. See the sources of ‘dirty’ NPM module for en example implementation of splitting — it’s cumbersome, so having an external dependency is well-grounded in this case.

Solution courtesy of: nponeccop

View additional discussion.