Simple post / sign system using event-emitter

This is from 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 determines that with this chat application:

"If you open several commands, you will see that everything that was typed in one command line echoes the other."

I've added console.log () events to try and debug what's going on. The only log is getting "data" when sending a message. I can start the server and connect to it via telnet, but any messages entered does not reflect any of the clients (including the client sending the message).

Can anyone shed some light on:

  • Why it doesn't work.
  • Whether this is an efficient or recommended code structure.
  • How it can be clarified / corrected
+3


source to share


1 answer


No events connect

for incoming sockets (sent back createServer()

). When the callback is called, the socket is already connected. So this is a mistake in the book.

You also need to be careful with the use this

.

IMHO is the best 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 event handler broadcast

that iterates over all connected sockets instead of adding a new event handler broadcast

for each individual socket.

+3


source







All Articles