1

我正在使用 .Net 框架 4.5.2,我将开始制作一个通知系统,该系统将通知从 Web 应用程序发送到从 Windows 窗体桌面应用程序连接的用户。

经过调查,我发现合适的解决方案是使用 signalR,因为它支持在将通知发送到连接的客户端之前过滤通知。

但我担心的是:当我在 Web 应用程序中创建 HUB 类时,我实现了 OnConnected 方法,该方法将检测连接到服务器以接收通知的任何客户端,我考虑在字典中收集连接的用户(在内存)我知道这是一个无法在生产中实现的解决方案,因为在内存变量(字典)中设置连接的用户是不可靠的。在我的情况下,连接用户的数量可能是 20,000 或更多,并且将来可能会变得更大。我需要知道跟踪所有连接用户的最佳方式,同时知道处理并发请求的最佳方式,而不会出现任何可伸缩性问题。我是这方面的新手,我必须尽快做出决定。

我还需要知道可以在集线器类中覆盖的 OnReconnect 方法的用途。

如果 iis 出于任何原因重新启动 Internet 应用程序,我还需要知道如何处理连接以不丢失。

4

1 回答 1

3

根据您要实现的目标,可以通过多种方式将连接映射到用户:

在内存存储中
最好的方法是使用并发字典。这将允许线程安全操作,但正如您所说,这不是大量连接的最佳解决方案。

永久外部存储
将您的映射保存在数据库中。
好的部分:映射可跨多个 Web 服务器
使用 坏的部分:数据库压力很大,需要进行大量清理

单用户
组 为每个用户创建一个组。这是最简单实用的解决方案。

好的部分:
〜真的很容易使用和实现
〜SignalR足够聪明,可以在断开连接时从
组中删除连接〜删除最后一个连接时会删除组
〜如果您使用Identity,您可以将唯一的组名存储为声明[1] [2]并将其放入您的集线器中,如下所示:

public static class IdentityExtensions
{
    public static string GetSignalRUniqueGroup(this IIdentity identity)
    {
        var claimsIdentity = identity as ClaimsIdentity;
        var claim = claimsIdentity?.FindFirst("uniqueSignalRGroup");
        if (claim == null) return null;

        try
        {
            return claim.Value;
        }
        catch
        {
            return null;
        }
    }
}

不是真的)不好的部分:你必须小心哪些用户加入了哪个组。!不要!在客户端实现加入组功能。相反,使用 OnConnected 和 OnReconnected 将连接添加到组

public override Task OnConnected()
{
    string userGroup = Context.User.Identity.GetSignalRUniqueGroup();
    if(userGroup != null) 
    {
        Groups.Add(Context.ConnectionId, userGroup);
    }

    return base.OnConnected();
}

public override Task OnReconnected()
{
    string userGroup = Context.User.Identity.GetSignalRUniqueGroup();
    if(userGroup != null) 
    {
        Groups.Add(Context.ConnectionId, userGroup);
    }       
    return base.OnReconnected();
}

public override Task OnDisconnected(bool stopCalled)
{
    //You should not manually remove the user from the group when the user disconnects. 
    //This action is automatically performed by the SignalR framework.
    return base.OnDisconnected(stopCalled);
}

对于其他问题,您可以阅读以下内容: Understanding and Handling Connection Lifetime Events in SignalR

于 2016-05-26T10:25:33.633 回答