所以我有一个用node.js编写的应用程序。我在同一台服务器上运行了这个应用程序的许多实例,并在启动应用程序时用参数指定了它们的“id”,如:
node app.js <ID>
我希望这个应用程序能够从任何其他实例接收消息,并将消息发送到任何其他实例。
因此,每个实例都在频道“app<ID>
”上“收听”消息,并且可以将消息发送到从“app1
”到“appN
”的任何频道。
实现这一目标的最佳方法是什么?一个redis服务器和它的pubsub系统? ZeroMQ或NSQ或类似的解决方案?可以使用socket.io吗?
答案 0 :(得分:2)
对于进程间通信(IPC),您可能会考虑node-ipc,这正是您在问题中描述的内容。它还具有允许跨不同主机进行通信的额外好处(如果您在多个服务器上扩展了应用程序)。
您的应用应该有一个主作为中心枢纽,然后辅助设备连接到它。
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);
}
});
});
注意:主也应连接到自身以接收来自其他辅助设备的事件!如果服务器代码和客户端代码在各自的模块中,那么您只需要从主进程中获取主进程并从每个进程(甚至是主进程)中请求辅助进程。