1

我正在使用 socket.io 为 iOS 应用程序和 androdi 应用程序开发一个聊天应用程序。我面临的问题是当客户端的网络连接突然丢失时,socket.io 服务器上的断开连接事件需要 25 秒(默认心跳间隔)才能被调用。调用断开连接事件时,我正在从我的数据库中删除 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 秒向服务器的心跳发送一次确认,那么如果应用程序长时间处于空闲状态,taht 可能会耗尽应用程序的电池。因此,我将不胜感激任何最适合我的解决方案。

谢谢

4

1 回答 1

1

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

你可以尝试的事情

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

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

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

  • 最重要的是,不要依赖 redis,您可以轻松地将其从结构中删除,并应用自定义 websocket 服务器,所有用户管理都内置在 node.js 中

于 2013-09-19T15:13:30.753 回答