nad*_*ada 5 cluster-computing redis node.js express socket.io
基于这个答案的问题:https://stackoverflow.com/a/18650183/4478897
我试图找到这个解决方案,但似乎没有任何东西可以按照我需要的方式工作.
集群expressjs,socket.io我们可以使用redis共享会话并io在ioworld(io.sockets.on('connection',...)内发送消息.问题是我们是想socket.join/leave在expressjs世界里发送消息(或使用简单的)(route.get/post).
如果我们不使用集群,我们可以atach客户socket对象明确request对象(或简单地export在io对象),然后在任何GET/POST路线随时使用它.
在另一方面,如果我们的集群和使用所提到的方法来获取socket里面的对象expressjs世界,有时socket对象,因为未定义socket此客户端对象在其他初始化worker.
一些示例流程:
worker 1处理此请求.socket.io.Worker 2处理此连接.worker 1或worker X处理此请求.在这种情况下,当客户端执行POST时,只worker 2知道socket该客户端的对象.所以这将得到一个未定义的socket对象.
那么,问题是:
我们如何socket从任何客户端对象中获取worker它以在expressjs request对象上重用它.
也许我的代码是错误的,但几乎就像上面提到的答案的链接.
笔记
使用最后的nodejs,socket.io,expressjs,socket.io-redis,redis ...版本
不要犹豫,不要问问题!
更新1
可能的解决方案,但仍需要测试它.不知道这是否真的很好:解决方案.
更新2
与更新1类似,但使用https://nodejs.org/dist/latest-v5.x/docs/api/cluster.html#cluster_event_message
nad*_*ada -1
好吧,终于尝试了代码,它可以工作(有一些拼写错误的修改和其他事情),但我确信这需要在某个地方有更好的代码。所以我愿意接受更多答案!
当授权客户端套接字和其他一些东西时,此代码是我的 socket.io 模块的一部分......
var redis = require("redis");
var redisPub = redis.createClient();
var redisSub = redis.createClient();
var PubSubChannel = "clusterChannel";
// Function that checks if this worker knows the socket object of this socketId.
// If not, publish the message to all the other sockets (workers)
io.socketDo = function (type, socketId, roomName) {
if (typeof io.sockets.connected[socketId] != "undefined") {
if (type === "join") {
return io.sockets.connected[socketId].join(roomName);
}
if (type === "leave") {
return io.sockets.connected[socketId].leave(roomName);
}
} else {
redisPub.publish(
PubSubChannel,
JSON.stringify({
type: type,
socketId: '' + socketId,
roomName: roomName
})
);
}
};
// Subscribe to some channel
redisSub.subscribe(PubSubChannel);
// When this worker receive a message from channel "PubSubChannel" checks
// if it have the socket object for this socketId and do the operation
redisSub.on("message", function (channel, data) {
data = JSON.parse(data);
var type = data.type;
var socketId = data.socketId;
var roomName = data.roomName;
if ((type === "join" || type === "leave") && channel == PubSubChannel){
if (typeof io.sockets.connected[socketId] != "undefined") {
if (type === "join") {
return io.sockets.connected[socketId].join(roomName);
}
if (type === "leave") {
return io.sockets.connected[socketId].leave(roomName);
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
然后只需导出模块并将其附加到您的expressjsrequest => req.io = io
// req.session.socketId value is fetched on "io.sockets.on('connection', function(socket) {"
// by express to socket.io using redis shared sessions
app.get('/', function (req, res) {
req.io.socketDo('join', req.session.socketId, 'someRoomToJoin');
// IT WORKS!
req.io.sockets.in('someRoomToJoin').emit('text');
req.io.socketDo('leave', req.session.socketId, 'someRoomToLeave');
res.send('Hello World!');
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
955 次 |
| 最近记录: |