如何处理哪个subprocess获得socket.io套接字句柄

我正在使用Socket.io和集群。 我需要做的是能够制作多个subprocess,并根据需要发送特定的[socket.io]套接字给每个进程。 当我尝试发送[socket.io]套接字作为句柄时,目前(见下面的代码)我得到一个exception。

我的代码下面没有它(因为我想获得最基本的例子工作),但我想要做的是让客户端连接,并告诉它什么过程去一些消息。 所以一个客户端会发送一个包含一些数据的'init'消息,并且基于这个数据,我将[socket.io]套接字转发给一个特定的进程。 这是我原来的计划。

我知道我可以从每个subprocesssocket.io侦听,但是当一个客户端只连接其中一个进程接收它。

我的两个问题是:

  1. 有没有办法发送一个socket.io套接字到subprocess?
  2. 如果没有,是否有另一种方式来决定哪个进程得到处理? (你可以在每个进程中使用不同的授权函数,如果一个进程不接受另一个进程可以的套接字)

var cluster = require('cluster'); if (cluster.isMaster) { var io = require('socket.io').listen(80); var cpuCount = require('os').cpus().length; var children = []; for (var i = 0; i < cpuCount; i += 1) { children.push(cluster.fork()); } //Master Process is listening for all connections io.sockets.on('connection', function (socket) { //upon a connection, send the 'handle' to a worker. children[0].send('server', socket); }); } else { process.on('message', function (m, handle) { //worker receives it here. console.log('here'); }); } 

控制台输出与堆栈跟踪:

 C:\Users\randy>node "C:\Users\randy\Documents\Visual Studio 2012\Projects\tesselconnect-server\tesselconnect-server\server.js" info - socket.io started debug - client authorized info - handshake authorized bZCM2CVpFFdU9eU1zYwx debug - setting request GET /socket.io/1/websocket/bZCM2CVpFFdU9eU1zYwx debug - set heartbeat interval for client bZCM2CVpFFdU9eU1zYwx debug - client authorized for debug - websocket writing 1:: child_process.js:427 throw new TypeError("This handle type can't be sent"); ^ TypeError: This handle type can't be sent at ChildProcess.target.send (child_process.js:427:15) at Worker.send (cluster.js:401:21) at SocketNamespace.<anonymous> (C:\Users\randy\Documents\Visual Studio 2012\Projects\tesselconnect-server\tesselconnect-server\server.js:16:15) at SocketNamespace.EventEmitter.emit [as $emit] (events.js:117:20) at connect (C:\Users\randy\node_modules\socket.io\lib\namespace.js:292:10) at C:\Users\randy\node_modules\socket.io\lib\namespace.js:308:13 at SocketNamespace.authorize (C:\Users\randy\node_modules\socket.io\lib\namespace.js:252:5) at SocketNamespace.handlePacket (C:\Users\randy\node_modules\socket.io\lib\namespace.js:302:14) at Manager.handleClient (C:\Users\randy\node_modules\socket.io\lib\manager.js:698:32) at Manager.handleUpgrade (C:\Users\randy\node_modules\socket.io\lib\manager.js:618:8) 

16号线:

 children[0].send('server', socket); 

您不应该以这种方式构build您的应用程序,因为它不会工作。 群集通常用于处理高负载,如果要传播负载,则可以使用群集和Redis存储。

除此之外,你不能发送一个Socket.IO套接字对象给一个工作者,因为它会失败这个检查:

 if (handle instanceof net.Socket) { message.type = 'net.Socket'; } else if (handle instanceof net.Server) { message.type = 'net.Server'; } else if (handle instanceof process.binding('tcp_wrap').TCP || handle instanceof process.binding('pipe_wrap').Pipe) { message.type = 'net.Native'; } else if (handle instanceof dgram.Socket) { message.type = 'dgram.Socket'; } else if (handle instanceof process.binding('udp_wrap').UDP) { message.type = 'dgram.Native'; } else { throw new TypeError("This handle type can't be sent"); } 

您无法真正select哪个工作人员将stream程发送给您,因此您应该考虑重组您的应用程序。 即使一个工作人员使用身份validation拒绝了一个套接字,客户端也不得不随机重新连接以find其预期的工作人员。

如果你需要不同的套接字来接收不同的数据,你应该看看房间或命名空间。 这是命名空间的工作方式:

 var nsp = io.of('/nsp'); nsp.on('connection', function(socket) { // use socket here as you would with the global namespace }); 

这就是房间的工作方式:

 io.sockets.on('connection', function(socket) { socket.join('room'); }); // emit to clients in that room io.sockets.in('room').emit('event_name', data);