2016-02-01 41 views
2

我想获得一个多进程节点。工人正在聆听客户的连接我需要通过套接字来掌握进程,因为主进程向客户端发送消息。工作人员也需要套接字来向客户发送消息。如何将节点中的套接字传递给集群

套接字是一个圆形对象,不能传递给主进程。

我的代码:

const cluster = require('cluster'); 

const http = require('http'); 
var io = require('socket.io'); 

var users; 
var clients = {}; 
if (cluster.isMaster) { 

function messageHandler(msg) { 
    if (msg.usersarray) { 
     usersarray = msg.usersarray; 
     console.log(usersarray); 
    }else if(msg.socket){ 
     clients[usersarray["manu"][0]] = msg.socket; 
     clients[usersarray["manu"][0]].emit("hola","hola");    
    } 
} 

// Start workers and listen for messages containing notifyRequest 
const numCPUs = require('os').cpus().length; 
for (var i = 0; i < numCPUs; i++) { 
    cluster.fork(); 
} 

Object.keys(cluster.workers).forEach((id) => { 
    cluster.workers[id].on('message', messageHandler); 
}); 


}else { 

// Create server & socket 

var server = http.createServer(function(req, res){ 
    // Send HTML headers and message 
    res.writeHead(404, {'Content-Type': 'text/html'}); 
    res.end('<h1>Aw, snap! 404</h1>'); 
}); 
server.listen(3000); 
io = io.listen(server); 

// Add a connect listener 
io.sockets.on('connection', function(socket) { 
    var hs = socket.handshake; 
    console.log("socket connected");  
    if(users == undefined){ 
     users = {}; 
    } 

    if(hs.query.usuario != undefined){ 

     if(users[hs.query.usuario] == undefined){ 
      users[hs.query.usuario] = new Array(); 
     }  

     users[hs.query.usuario].push(socket.id); // connected user with its socket.id 
     clients[socket.id] = socket; // add the client data to the hash 
     process.send({ usersarray: users}); 
     process.send({ socket: socket}); 
    } 

    // Disconnect listener 
    socket.on('disconnect', function() { 
     console.log('Client disconnected.'); 
    }); 
}); 
} 
管线process.send

({插座:插座});节点js得到错误“TypeError:将圆形结构转换为JSON”

-I使用了一些模块来转换圆形对象但不工作。

-I试图通过套接字ID,然后在主进程中,创建了与此ID的新套接字,但我不知道使用它。

有什么可能性将socket从worker传递给master进程?

节点JS版本:V5.5.0

回答

1

嗯,我不认为这是可能是你正在尝试做的。当你创建一个集群时,这意味着你创建了独立的进程(master + worker),它们只能通过管道进行通信。

在管道上交谈意味着他们只能向对方发送字符串。 process.send尝试使用JSON.stringify将一个JavaScript对象序列化为JSON( - >制作一个字符串)。例如JSON不能有函数,圆圈等。我只是检查socket对象,它非常复杂并且包含函数(如socket.emit()),所以你不能只是序列化它并通过管道发送它。

也许你可以检查thisthis关于如何使用群集WebSockets。

这似乎并不是很微不足道。也许您可以将CPU密集型任务传递给某些工作进程(通过群集或自己产生它们),将结果发送回主服务器并让他完成所有与客户端?

-1

我知道你的目的是向群集中的所有节点工作进程广播,尽管你不能发送套接字组件,但是有一个解决方法来提供服务。我会尝试用一个例子的解释:

步骤1:当客户端操作需要的广播:

Child.js(过程已经分叉):

socket.on("BROADCAST_TO_ALL_WORKERS", function (data) 
{ 
    process.send({cmd : 'BROADCAST_TO_ALL_WORKERS', message :data.message}); 
}) 

步骤2:在集群创建端

Server.js(发生集群分叉的地方):

if (cluster.isMaster) { 

    for (var i = 0; i < numCPUs; i++) { 

    var worker = cluster.fork(); 

    worker.on('message', function (data) { 
    if (data.cmd === "BROADCAST_TO_ALL_WORKERS") { 
     console.log(server_debug_prefix() + "Server Broadcast To All, Message : " + data.message + " , Reload : " + data.reload + " Player Id : " + data.player_id); 
     Object.keys(cluster.workers).forEach(function(id) { 
      cluster.workers[id].send({cmd : "BROADCAST_TO_WORKER", message : data.message}); 
     }); 
     } 
    }); 
    } 

    cluster.on('exit', function (worker, code, signal) { 
    var newWorker = cluster.fork(); 
    newWorker.on('message', function (data) { 
     console.log(data); 
     if (data.cmd === "BROADCAST_TO_ALL_WORKERS") { 
     console.log(data.cmd,data); 
     Object.keys(cluster.workers).forEach(function(id) { 
      cluster.workers[id].send({cmd : "BROADCAST_TO_WORKER", message : data.message}); 
     }); 
     } 
    }); 
    }); 
} 
else { 
    //Node Js App Entry 
    require("./Child.js"); 
} 

第3步: - 在儿童> io.on之前将这个( “连接”)要在子进程

广播。js

process.on("message", function(data){ 
    if(data.cmd === "BROADCAST_TO_WORKER"){ 



    io.sockets.emit("SERVER_MESSAGE", { message: data.message, reload: data.reload, player_id : data.player_id }); 
} 
}); 

我希望它很清楚。请评论它是否令人困惑......我会尽力说清楚。