我使用.NET 2.2的核心与ASP.NET核心SignalR。目前,我已把全部的连接状态在SQL数据库(见this document;即使它是“老” SignalR库手动,逻辑是一样的)。我还使用一个Redis的背板,因为我的应用程序可以水平扩展。
但是,重新启动我的应用程序时,当前的连接没有得到关闭,将得到孤儿。以前链接的文章指出:
如果你的Web服务器停止工作或重新启动应用程序,该OnDisconnected方法不叫。因此,有可能是你的数据仓库将有连接ID不再有效记录。要清理这些孤立的记录,你不妨无效,这是一个时间表,是有关您的应用程序之外创建的任何连接。
在“老” SignalR还有一个ITransportHeartbeat
(其中this script完全实现),但有对.NET Core版本(ATLEAST,我无法找到它)没有这样的接口。
我怎么知道连接是否不再活着吗?我想(或实际需要),以清理旧连接ID。
我想出了解决办法如下。这不是优雅,但现在我看没有其他选择。
我更新了模型在数据库中不仅包含ConnectionId
也是一个LastPing
(这是一个DateTime
型)。客户端发送消息KeepAlive
(自定义消息,不使用SignalR存活设置)。在接收到消息(服务器端),我更新与当前时间的数据库:
var connection = _context.Connection.FirstOrDefault(x => x.Id == Context.ConnectionId);
connection.LastPing = DateTime.UtcNow;
要清理孤立的连接(未通过SignalR的OnDisconnected
方法去除),我有一个任务(目前在迟发型),从而消除在LastPing
领域还没有被最近更新的连接定期运行。