Nodejs socket.io 在多线程下怎么通信
Nodejs socket.io 在多线程下怎么通信
在用socket.io做web聊天系统的时候为了解决nodejs的单线程易崩溃的状况,使用cluster.fork()多开了些线程,有此带来的问题是每一个线程都有自己的socket,多个浏览器测试发现有的时候能进入同一个进程就可以通信,没有进入的话后台狂打印信息 debug - cleared heartbeat interval for client xDbxAhAOkoQHfQWC7TGT debug - discarding transport debug - client authorized info - handshake authorized wGNiKiQxge2j1tpQ7TGV debug - client authorized info - handshake authorized A50oRdQZNg27S2Hr7TGW debug - setting request GET /socket.io/1/websocket/wGNiKiQxge2j1tpQ7TGV debug - set heartbeat interval for client wGNiKiQxge2j1tpQ7TGV debug - websocket writing 7:::1+0 warn - client not handshaken client should reconnect info - transport end (error) debug - set close timeout for client wGNiKiQxge2j1tpQ7TGV debug - cleared close timeout for client wGNiKiQxge2j1tpQ7TGV debug - cleared heartbeat interval for client wGNiKiQxge2j1tpQ7TGV debug - discarding transport debug - client authorized info - handshake authorized BmULkJ6v4etxDReY7TGX debug - setting request GET /socket.io/1/websocket/BmULkJ6v4etxDReY7TGX debug - set heartbeat interval for client BmULkJ6v4etxDReY7TGX debug - websocket writing 7:::1+0 warn - client not handshaken client should reconnect info - transport end (error) 一直不停打印,想知道是为什么?以及解决问题的思路? 有一个想法是把socket只写到主线程里,就是写到一个线程里,其他线程不管,看这样想是否正确呢?
可以使用 pomelo
需要这么复杂啊,不懂哦
楼主,Node cluster这叫多进程。
socket.io 可以通过redis 来进行进程/集群之间的状态和信息共享。在configuring socket.io里面的store
这段里面有描述
分享一下文章,Cloud Foundry 是這樣達到多綫線溝通的
主要看下第三部份,把 PubSub 放到 Redis 去做 因為提到多綫程,想必也要做相關的配置,這裏說的比較清晣,我們也這配置這個環境。
是你的多进程之间状态没有共享吧?
socket一旦连接,就是固定与客户端相连的。
在使用 socket.io
进行 Web 聊天系统的开发时,如果通过 cluster.fork()
开启了多线程,那么每个线程(即工作进程)都会有自己的 socket 服务器实例。这会导致不同的客户端连接到不同的线程,从而无法实现跨线程间的直接通信。
解决方案
解决这一问题的方法是在主进程中集中处理所有 socket.io 的通信,然后将消息转发给相应的子进程。下面是具体步骤:
- 主进程管理 socket.io:所有的 socket 连接都在主进程中创建和维护。
- 子进程接收消息:当主进程收到消息后,根据消息内容选择合适的子进程进行消息转发。
- 消息传递机制:可以通过进程间通信(IPC)来实现在主进程与子进程之间的数据交换。
示例代码
主进程代码
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
const io = require('socket.io')(server);
if (cluster.isMaster) {
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
const workers = [];
cluster.on('online', function(worker) {
console.log(`Worker ${worker.process.pid} is online`);
workers.push(worker);
});
io.on('connection', function(socket) {
// 根据需要分配 socket 连接到特定的工作进程
let workerIndex = socket.id % numCPUs;
let worker = workers[workerIndex];
console.log(`Socket ${socket.id} assigned to Worker ${worker.process.pid}`);
// 建立 IPC 通道
worker.send('socket', socket.id);
worker.on('message', function(msg, workerId) {
console.log(`Message from worker ${workerId}:`, msg);
io.to(socket.id).emit('response', msg);
});
});
}
子进程代码
process.on('message', function(m, socketId) {
if (m === 'socket') {
// 监听来自主进程的消息
io.sockets.socket(socketId).on('message', function(data) {
// 处理数据并发送响应
this.emit('response', data);
});
}
});
总结
通过上述方法,我们可以在 Node.js 中使用 socket.io
和多线程来实现跨线程的通信。关键在于让主进程管理所有 socket 连接,并利用 IPC 将消息分发到正确的子进程中。