如何在socket.io中使客户端立即断开网络丢失?

时间:2013-09-19 14:05:13

标签: node.js sockets websocket socket.io chat

我正在使用socket.io为iOS应用程序和androdi应用程序开发聊天应用程序。面临的问题是当客户端突然丢失网络连接时,socket.io服务器上的disconnect事件需要25秒(默认心跳间隔)才能被调用。我在调用disconnect事件时从我的db中删除了socket.id/username。但是在这25秒内,socket.id/username仍然存在于我的数据库中,当其他一些用户向失去网络连接的用户发送消息时,即使它从未被传递,它也会显示为已发送。解决方案可能是将心跳间隔减少到1或2秒。我试过了,但奇怪的是它没有被设置,它仍然需要25秒左右。以下是我的代码

var app = require('express')()
 , server = require('http').createServer(app)
 , sio = require('socket.io')
 , redis = require('redis');

var client = redis.createClient();
var io = sio.listen(server, { origins: '*:*' });

io.set("store", new sio.RedisStore);

io.set("heartbeat interval", 2);    

var azure = require('azure');

server.listen(4002);

但即使我将心跳间隔设置为2秒,我认为可能存在不利因素。如果移动应用程序每隔2秒向服务器的心跳发送确认,那么如果应用程序长时间处于空闲状态,则可能会耗尽应用程序的电池电量。所以我会感谢所有在我的案例中效果最好的解决方案。

由于

1 个答案:

答案 0 :(得分:0)

有许多变量需要考虑,何时断开客户端,因为25secs是一种小间隔检查方式,特别是如果你的应用程序说100.000个用户。

你可以尝试的事情

  • 客户端控制,查看用户是否正在键入或甚至触摸设备以获取用户状态空闲|活动|僵尸。

  • 不要在客户端发出断开连接后立即从redis中删除用户,而是将用户置于toDisconnect队列列表中,或者设置其他变量,如果同一用户再次连接然后你可以简单地移动对象,而不是再次查询来创建对象。

  • 如果对结果仍不满意,请尝试使用二进制websockets,至少它会从数据包中删除一些开销,并且它们会更快地传递,因为它的大小更小。

  • 底线,不依赖redis,您可以轻松地从结构中删除它,并应用自定义websocket服务器,并在node.js中构建所有用户管理