1

I am currently working on a node.js-based socket.io service that makes use of the node.js cluster module to spawn several node.js processen on the same machine.

The socket.io docs say that it is required to use an adapter if multiple processes are used, so that e.g. broadcasting targets not only the clients connected to the current process, but to all connected clients of every process.

  1. Do I understand it correctly, that I am required to use such an adapter even if all processes are spawned locally (i.e. not across several servers)?
  2. The server processes need to communicate from time to time (just unidirectional, i.e. broadcast a message without the need for a response). If such an adapter is in use (e.g. socket.io-redis), can I use it to broadcast to all server processes as well? Or are the adapters only used to target connected clients?
muffel
  • 7,004
  • 8
  • 57
  • 98

1 Answers1

10

This is a late answer to your question ( one year later ) ... I'm sure you've figured out by now but if anyone else just learning comes across this...

  1. You do require an adapter ( socket.io-redis ) if you want to send messages across multiple node.js processes on the same machine. There is no other way currently to manage multiple sockets across different app instances and sometimes no guarantee that the client is connecting to the same instance while using the app so the adapter manages that socket connection information for you.

  2. You can code the sockets to communicate however you would like once the adapter is in place ( assuming your libraries work well together - see my related question ).

socket.broadcast.emit will communicate to all sockets except the sending socket

io.sockets.emit will communicate to all sockets

socket.emit will communicate to just that socket

Example:

// Server

var redisPort = 6379
var io = require('socket.io');
var redisAdapter = require('socket.io-redis');

io = io.listen( httpServer ); //the server instance ( supply your own code here )

io.adapter( redisAdapter({ host: 'localhost' , port : redisPort }) );//6379
io.on('connection', function( socket ){
    
    socket.on('client-msg', function( data ){
        var msgObject = { content : '' , status : 0 };
        if( data && data.content ){
            msgObject.content = data.content;
            msgObject.status = 1;
        }
        
        io.emit('server-response', msgObject );//send to all sockets
        socket.emit( 'server-response', msgObject );//send to this socket
        socket.broadcast.emit( 'server-response', msgObject ); //send to all other sockets but not this one
    
    });
    
    socket.on('disconnect', function( data ) { 
        //do some stuff unrelated to emitting                           
    });
});

// Client
var socketio = io.connect( window.location.origin  , { transports : ['websocket'] } );

socketio.emit("send-message" , { content : msg  });

socketio.on("server-response", function( data ) {
    console.log( data.content , data.status );
});

Note: the ( sparse ) socket.io docs also mention a socket.io-emitter library can be used with the adapter... I am able to send/receive messages across multiple app instances without so... I'm not sure what it is good for to be honest.

noam aghai
  • 1,364
  • 3
  • 18
  • 30
Squivo
  • 917
  • 1
  • 10
  • 21
  • 1
    The emitter is used for node processes that do not have a socket.io server instantiated, ex. for pure job workers – Climax Feb 27 '17 at 09:16