Reputation: 284
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.
Upvotes: 3
Views: 11520
Reputation: 1806
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.
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.
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:
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:
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')
?
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.
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);
});
Upvotes: 8
Reputation: 62
Please read the official Nodejs document for module 'net'.
The crux of your matter is, you have a server socket that you have named 'client' (a confusing name) and it is not a client socket. For a client socket you can subscribe to 'connect' event and not for a server socket.
net.createServer(callback)
takes a callback which is called back when a new connection from a client occurs and the callback is passed the server socket. What you are referring to in function(client)
is essentially a server socket and the term used 'client' is misleading. Please see the Node.js 'net' module example of createServer
. For a server socket all the events listed (e.g data, timeout, end, close etc) are valid except the 'connect' event.
On the contrary to a server socket, if you are to create a client program where you called net.createConnection
that will return you a client socket. Of that socket you subscribe to the 'connect' event.
Upvotes: 0
Reputation: 802
If your code is same as:
var Client = require('net').createConnection,
client = Client({port:4321});
client.on('connect', function(){
//channel.emit('join', id, client);
channel.emit('join', id, this); //avoid bad closure
});
It is valid code and when connect
will emited, the server part emits connection
, creates socket object and pass it to connection
callback
UPDATE:
Your code is incorrect. You pass to createServer
the callback for connection
event it same as:
var server = net.createServer();
server.on('connection', callback);
In callback you have yet connected socket object. This is correct:
var server = net.createServer(function (client) {
var id = client.remoteAddress + ':' + client.remotePort;
channel.emit('join', id, client);
client.on('data', function(data) {
data = data.toString();
channel.emit('broadcast', id, data);
});
});
Upvotes: 2