Reputation: 2312
This is from the book Node.JS in Action, chapter 3, example 11. Page 52.
var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};
//Add a listener for the join event that stores a user’s client object,
//allowing the application to send data back to the user.
channel.on('join', function(id, client) {
console.log('join fired');
channel.clients[id] = client;
this.subscriptions[id] = function(senderId, message) {
console.log('broadcast fired');
//ignore data if it’s been directly broadcast by the user.
if (id != senderId) {
this.clients[id].write(message);
}
}
//Add a listener, specific to the current user, for the broadcast event.
this.on('broadcast', this.subscriptions[id]);
});
var server = net.createServer(function(client) {
var id = client.remoteAddress + ':' + client.remotePort;
client.on('connect', function() {
console.log('connect fired');
//Emit a join event when a user connects to the server, specifying the user ID and client object.
channel.emit('join', id, client);
});
client.on('data', function(data) {
console.log('data fired');
data = data.toString();
//Emit a channel broadcast event, specifying the user ID and message, when any user sends data.
channel.emit('broadcast', id, data);
});
});
server.listen(8888);
It stats that with this chat application:
"If you open up a few command lines, you’ll see that anything typed in one command line is echoed to the others."
I added the console.log() events to try and debug what was going on. The only log is get is the 'data fired' when sending a message. I'm able to launch the server, and connect to it via telnet, but any messages entered do not echo to any of the clients (including the client sending the message).
Can anyone shed some light on:
Upvotes: 3
Views: 6137
Reputation: 106736
There is no connect
event for incoming sockets (passed to the createServer()
callback). When the callback is called, the socket is already connected. So this is an error in the book then.
You should also be careful of this
usage.
IMHO here is a better example:
var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};
channel.on('join', function(id, client) {
channel.clients[id] = client;
channel.subscriptions[id] = function(senderId, message) {
if (id !== senderId)
channel.clients[id].write(message);
}
channel.on('broadcast', channel.subscriptions[id]);
}).on('leave', function(id, client) {
// cleanup on client disconnect
console.log('user ' + id + ' has left');
delete channel.clients[id];
channel.removeListener('broadcast', channel.subscriptions[id]);
delete channel.subscriptions[id];
});
var server = net.createServer(function(client) {
var id = client.remoteAddress + ':' + client.remotePort;
console.log('user ' + id + ' has joined');
channel.emit('join', id, client);
client.on('data', function(data) {
channel.emit('broadcast', id, data.toString());
}).on('close', function() {
channel.emit('leave', id, client);
});
});
server.listen(8888);
A further improvement would be to have only one broadcast
event handler which loops over all connected sockets instead of adding a new broadcast
event handler for every single socket.
Upvotes: 3