如何将套接字传递到节点中的群集
How to pass socket to cluster in node
我想得到一个多进程节点。工作人员正在监听客户端连接。我需要将套接字传递给主进程,因为主进程向客户端发出消息。工作线程还需要套接字来向客户端发出消息。
套接字是一个循环对象,不能传递给主进程。
我的代码:
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.');
});
});
}
in line process.send({ socket: socket}); Node js 收到错误"类型错误:将循环结构转换为 JSON"
-我使用了一些模块来转换圆形对象,但不起作用。
-我尝试传递套接字 id,然后在主进程中,使用此 id 创建新套接字,但我不知道如何使用它。
是否有可能将套接字从工作进程传递到主进程?
节点js版本:v5.5.0
嗯,我认为你不可能想做什么。创建集群时,这意味着您创建了单独的进程(主进程 + 工作进程),这些进程只能通过管道进行通信。
通过管道交谈意味着他们只能相互发送字符串。 process.send
尝试使用 JSON.stringify 将 Javascript 对象序列化为 JSON(>从中生成字符串)。例如,JSON不能有函数,圆圈等。我刚刚检查了socket
对象,它非常复杂并且包含函数(例如socket.emit()
),因此您不能只是序列化它并通过管道发送它。
也许你可以检查这个或这个如何使用集群WebSockets。
这似乎不是一件小事。也许您可以将 CPU 密集型任务传递给一些工作进程(通过集群或只是自己生成它们),将结果发送回主进程并让他与客户端进行所有通信?
我理解您广播到集群中所有节点工作进程的目的,尽管您不能发送套接字组件,但有一个解决方法可以达到目的。我将尝试用一个例子来解释:
步骤 1:当客户端操作需要广播时:
子.js(已分叉的进程):
socket.on("BROADCAST_TO_ALL_WORKERS", function (data)
{
process.send({cmd : 'BROADCAST_TO_ALL_WORKERS', message :data.message});
})
步骤 2:在群集创建端
服务器.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("连接")之前 在 Child.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 });
}
});
我希望它清楚。如果令人困惑,请发表评论...我会尽量说清楚。
- 节点导出返回一个空对象
- 可以前端maven插件使用节点,npm已经安装
- 在jstree中,如何将指定的节点集中到大型树上
- 节点Js:How to catch a“;没有这样的文件或目录“;读取线模块出错
- 如何从模块链中调用函数.导出到节点中
- 节点是否需要模块传递带有方括号的arg?这是个错误吗
- d3基于用户选择动态更新节点
- 有条件更新d3.js力图中节点的最佳方法
- 如何处理node.js节点mongodb中的连接和查询队列
- 将DOM节点值与字符串Javascript进行比较
- 节点fs.stat名称未定义
- 无法安装节点sass相关性
- 节点协同与生成器和Promise并行流量控制
- 节点.js将变量显示为 HTML
- 将节点数据分配给另一个变量jstree
- 如何在动态创建的节点上绑定函数
- 节点.js群集
- 节点群集未将任务分派给另一个可用的工作线程
- 如何将套接字传递到节点中的群集
- 对节点应用程序进行群集时Socket.io websocket授权失败