【发布时间】:2014-05-18 22:46:02
【问题描述】:
我正在编写一个 nodejs/socket.io 应用程序,它使用 AWS Elasticache 中的集群和 Redis 作为 RedisStore 后端。该应用程序在房间周围大量工作,我很难理解为什么只有 Mobile Safari(iPad mini Retina iOS7)在发出请求后不能离开它订阅的房间。即使从客户端关闭连接也会使套接字在服务器上嗡嗡作响,并且对房间的订阅完好无损,但其他浏览器可以毫无问题地退出。
- NodeJS v0.10.25
- Socket.io v0.9.16
- Redis v2.8.6 (AWS Elasticache)
- Ubuntu 14.04 LTS(EC2 在 TCP 模式下的负载均衡器后面)
现在,在我的代码中,我一直在使用 io.sockets.manager.roomClients 对象来遍历并查看哪些房间实际在服务中。这是因为io.sockets.clients() 在连接打开和关闭一段时间后报告的数据完全不准确。
我的代码实在是太长了,不能放在这里,而且相当私密,但基本上我所拥有的就是:
服务器:
if (cluster.isMaster) {
function heartbeat(){
// io.sockets.clients() doesn't splice dropped connections off the array
// so we have to use io.sockets.manager.roomClients to see active rooms
for( var i in io.sockets.manager.roomClients ) {
console.log("Client:", i, io.sockets.manager.roomClients[i] );
}
setTimeout(heartbeat,5000);
}
heartbeat();
} else {
io.sockets.on('connection', function (socket) {
socket.on('subscribe', function (room) {
console.log("Starting:",room);
socket.join(room);
});
socket.on('unsubscribe', function (room) {
console.log("Leaving:",room);
socket.leave(room);
});
socket.on('disconnect', function () {
console.log("Close Shop");
});
});
}
客户:
socket.emit('subscribe', 'some-room');
服务器日志
Starting: some-room
然后我得到一个 Client 日志,每个超时滴答声:
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
现在,问题就在这里。如果我取消订阅或与桌面浏览器断开连接:
socket.emit('unsubscribe', 'some-room');
Leaving: some-room
或者
socket.disconnect();
Close Shop
刻度看起来像这样:
Client: lhZsH1oL2vV7BML9QkSW { '': true }
我希望如此,因为我们知道,socket.io 在连接清理方面很糟糕,但至少房间订阅已经消失了。但是,在我的平板电脑上,取消订阅或断开连接后,房间订阅仍保留在 io.sockets.manager.roomClients 对象中:
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
我在套接字编程方面相当新,所以我确定我遗漏了一些明显的东西,但是有没有人在移动 websockets 方面遇到过类似的问题?
【问题讨论】:
-
我偶尔也会遇到这种情况。通常套接字最终会断开连接,但那是在几分钟后.. 希望你能找到答案!
-
@lawm,谢谢!是的,果然,在让它静置几分钟后,客户端队列被清除了。我可能最终只是暂时放手,但如果这项服务变得很大,我想找到一种方法来强制删除东西以释放内存。我会发布任何更新
标签: node.js socket.io mobile-safari node-redis amazon-elasticache