Reputation: 1851
So I have an app written in node.js. I run many instances of this app in the same server and specify their "id" with an argument when starting the app, like:
node app.js <ID>
I would like this app to receive messages from any other instance, and send messages to any other instance aswell.
So each instance is "listening" messages on channel "app<ID>
" and can send messages to any channel from "app1
" to "appN
".
What is the best way to achieve this? A redis server and it's pubsub system? ZeroMQ or NSQ or similar solutions? Can socket.io be used?
Upvotes: 4
Views: 3242
Reputation: 53526
For inter-process communication (IPC), you might consider node-ipc which is exactly what you're describing in your question. It also has the added bonus to allow communication across different hosts (if you ever expand your app on multiple servers).
Your app should have a master acting as central hub, then auxiliaries connecting to it.
const ipc=require('node-ipc');
ipc.config.id = 'world';
ipc.config.retry = 1500;
ipc.serve(function() {
ipc.server.on('app.event', function(data, socket) {
// broadcast to all clients
ipc.server.broadcast('app.event', data);
});
);
ipc.server.start();
const ipc=require('node-ipc');
const EventEmitter = require('events');
// export our event emitter
const events = module.exports = new EventEmitter();
ipc.config.id = 'client' + CID; // CID = from args
ipc.config.retry = 1500;
ipc.connectTo('world', function() {
const _emit = events.emit; // preserve old emit function
ipc.of.world.on('connect', function() {
ipc.log('## connected to world ##', ipc.config.delay);
// override event emitter's emit function
events.emit = function (event, data) {
ipc.of.world.emit('app.event', {
id: ipc.config.id,
event: event,
data: data
});
};
});
ipc.of.world.on('disconnect', function() {
ipc.log('disconnected from world');
// can't emit anymore, so just noop
events.emit = function () {};
});
ipc.of.world.on('kill.connection', function(data) {
ipc.log('world requested kill.connection');
ipc.disconnect('world');
});
ipc.of.world.on('app.event', function(data) {
ipc.log('got a message from world : ', data);
if (data.id !== ipc.config.id) {
// fire events listeners
_emit.call(events, data.event, data.data);
}
});
});
Note: The master should also connect to itself to receive events from other auxiliaries! If the server code and client code are in their respective modules, then you only need to require the master from your master process and auxiliary from every processes (even master).
Upvotes: 3