Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node js net event : connect vs connection

Tags:

node.js

When is the connection event of the net.Server fired vs the net.Socket connect event. Are they the same event? I have seen a code example where the handler for the net.createServer function (which handlers the connection event) also has the following code in it

    var server = net.createServer(function (client) {
var id = client.remoteAddress + ':' + client.remotePort;
client.on('connect', function() {
channel.emit('join', id, client);
});
client.on('data', function(data) {
data = data.toString();
channel.emit('broadcast', id, data);
});
});

Is this incorrect? Is this listener not needed/never hit..i.e. the emit should be outside the listener.

like image 506
MikeC Avatar asked Mar 11 '26 09:03

MikeC


1 Answers

Based on the code you post here, I'll assume you are reading Node.js in Action and it's the sample code that cause you the problem. If this is the case, you may reference to this similar question: NodeJS events on('connect') error.

Summary

In short, these 2 events are received by 2 different objects.

connect event is received by socket object and is emitted "when a socket connection is successfully established". On ther other hand, connection event is received by server object and is emitted "when a new connection is made".

Notice when a client hit node and create a socket, the callback for net.createServer(callback) is automatically called, thus you don't have to manually register another event handler on this client-server socket, which is client.on('connect', function() { }); in your code.


Concepts

As @3y3 mentioned, there are 2 ways to use net module in node.js, which are createConnection and createServer.

To better understand how it works, you may use this diagram as sample:

enter image description here

net.createServer

When you require net module and createServer, you basically create a server for clients (browser via http, terminal via telnet, etc.) to connect in.

Consider the following codes:

var net = require('net');
var events = require('events');    

var channel = new events.EventEmitter();

var server = net.createServer(function (socket) {
  var id = socket.remoteAddress + ': ' + client.remotePort;
  console.log('Server connected', id);
  channel.emit('join', id, socket);

  socket.on('data', function(data) {
    data = data.toString();
    channel.emit('broadcast', id, data);
  });
}).listen(8888);

In this case, the parameter in the callback of createServer is the "socket" between server and client. In the sample code, the author of Node.js in Action call it client, which might be a little confusing for you, but that's actually the same concept: it's a client related object which contains methods for your server to do something.

Notice that this callback is registered on the server and called at the same time the connection is built. This is a result of connection event which is emitted to the server when the client hit port 8888 on server in this case. Any functions you put inside this callback will be execute immediately. In our case, there are three things we did:

  • Console.log the client id on server
  • Emit a 'join' event to channel object
  • Register a event listener for 'data' event (i.e. called when there's data sending from client)

There's no need for client.on('connect', function() { // do something }), and since the callback for server connection event is the one we just mentioned. So what's the purpose of clinet.on('connect')?

net.createConnection

By utilizing this function, you create "a connection to the server" rather then create a server itself. In other words, it just like you open a terminal and use telnet to connect to the server, only that this happens in your server code base (i.e. in your node environment, as the diagram Client x shows)

Consider the following code: (based on @3y3's example again):

var Client = net.createConnection;
var client = Client({port: 8888, localAddress: '127.0.0.1', localPort: 51000});

client.on('connect', function() {
  var id = this.localAddress + ': ' + this.localPort;
  console.log('Client connected', id);
});

Here, we build a client in node and connect to the server through port 8888, which is what we defined previously. localPort and localAddress are defined arbitrary, just a mimic for a terminal connection in local environment.

We then register an event handler on this client, so when this client is connected to the server, it will receive a connect event and execute this event handler. If you run both snippets in the same file with node, you'll see both

Client connected 127.0.0.1: 51000
Server connected ::ffff:127.0.0.1: 51000

in the console.


Conclusion

If you want to do something when remote clients connect to the server, simply put lines you want to execute in the callback function of net.createServer(function(socket) { // your lines here }).

Use client.on('connect', function() {}); for other manually build clients in your node environment.

For further information about socket object and server object, you may refer to the official document here.

You can play with the following revised codes in your case:

var events = require('events');
var net = require('net');

var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};

channel.on('join', function (id, client) {
  this.clients[id] = client;
  this.subscriptions[id] = function (senderId, message) {
    if (senderId !== id) {
      this.clients[id].write(message);
    }
  };

  this.on('broadcast', this.subscriptions[id]);
});

var server = net.createServer(function (client) {
  var id = client.remoteAddress + ': ' + client.remotePort;
  console.log('Server connected', id);
  channel.emit('join', id, client);

  client.on('data', function(data) {
    data = data.toString();
    channel.emit('broadcast', id, data);
  });

});

server.listen(8888);

var Client = net.createConnection;
var client = Client({port: 8888, localAddress: '127.0.0.1', localPort: 51000});

client.on('connect', function() {
  var id = this.localAddress + ': ' + this.localPort;
  console.log('Client connected', id);
});
like image 77
kavare Avatar answered Mar 14 '26 00:03

kavare



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!