5

[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.

João Pinto Jerónimo
  • 9,586
  • 15
  • 62
  • 86
  • Could you clarify the reasons not to use socket.io? – MaximG Aug 03 '11 at 21:52
  • 1
    It's supposed to be a very simple TCP server that accepts connections from regular TCP clients and not a web page... – João Pinto Jerónimo Aug 03 '11 at 22:01
  • 1
    http://github.com/visionmedia/masteringnode/raw/master/book.pdf => read chapter about events at least. socket.io abstracts that on top of net API using events. – Alfred Aug 03 '11 at 22:13
  • 1
    @Alfred will do! But the sections after and including TCP are empty... But I think I can find the complete PDF somewhere else .. – João Pinto Jerónimo Aug 03 '11 at 22:24
  • @Pinto not yet written ;). But events are important :) – Alfred Aug 03 '11 at 22:25
  • @Alfred yep, found out now... I read about EventEmitter, that's exactly what I'm aiming at... But other languages won't have similar things and for instance a python script won't be able to emit events that a nodejs tcp server would catch.. right ? – João Pinto Jerónimo Aug 03 '11 at 22:31
  • exactly sockets are real simple. You can only read something from it and write something to it. Language agnostic though... – Alfred Aug 03 '11 at 22:36
  • @JoãoPintoJerónimo let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2112/discussion-between-alfred-and-joao-pinto-jeronimo) – Alfred Aug 03 '11 at 22:36

3 Answers3

6

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.

nponeccop
  • 13,527
  • 1
  • 44
  • 106
1

Socket.io uses socket.io-parser's encode/decode method to transfer messages between server and client, which means it actually uses stream under the hood.

springuper
  • 508
  • 4
  • 11
-1

Just wanted to mention that in Nodejs Version 5.0.0, there's already a client in case you wanna skip using lazy:

var client = net.connect({port: 8000},
    function() { //'connect' listener
       console.log('connected to server!');
});

client.on('data', function(data) {
  console.log(data.toString());
  client.end();
});

client.on('end', function() {
  console.log('disconnected from server');
});
ambodi
  • 6,116
  • 2
  • 32
  • 22