我正在编写一个 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(TCP 模式下负载均衡器后面的 EC2)
现在,在我的代码中,我一直在使用该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 有类似的问题?