我正在使用iOS应用程序和Androdi应用程序的 socket.io 开发聊天应用程序。我面临的问题是,当客户端上的网络连接突然丢失时,调用 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 秒向服务器的心跳发送一次确认,那么如果应用程序长时间闲置,这可能会耗尽应用程序的电池电量。因此,我将不胜感激任何最适合我的解决方案。
谢谢
变量需要考虑,何时断开客户端的连接,因为 25 秒是一种小间隔检查某些内容的方法,特别是如果您的应用程序有 100.000 个用户。
你可以尝试的事情
客户端控制,查看用户是否正在键入甚至触摸设备以获取用户状态 idle|active|zombie。
不要在客户端发出断开连接后立即从 Redis 中删除用户,而是可以将用户放入
toDisconnect
队列列表中,或设置其他变量,如果同一用户再次连接,那么您可以简单地移动对象,而不是再次查询以创建对象。如果仍然对结果不满意,请尝试二进制 WebSockets,至少它会从数据包中消除一些开销,并且它们的交付速度会更快一些,因为大小较小。
最重要的是,不要依赖 Redis,您可以轻松地将其从结构中删除,并应用自定义 WebSocket 服务器,并在 Node 中构建所有用户管理.js