在 SiganlR 中处理并发连接 [英] Handling concurrent connections in SiganlR

查看:76
本文介绍了在 SiganlR 中处理并发连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using .Net framework 4.5.2 and I will start to make a notification system that send notifications from web application into users that are connected from windows forms desktop application .

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

after investigations i found that the suitable solution is using signalR as it supports filtering the notification before sending it to the connected clients .

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

but my concern here is that : when i created my HUB class in the web application , i implemented the method OnConnected that will detect any client who is connected to the server to recieve the notifications , i thought about collecting the connected users in dictionary (in memory) i know it is a solution that couldn't be implemented in the production as this is not reliable to set the connected users in a memory variable (dictionary) . In my case the number of connected users may be 20,000 or over and it may get larger in future . I need to know the best way to track all connected users and at the same time the bets way to handle the concurrent requests without having any scalability issues . I am new in this and i have to make my decision very fast please.

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

I also need to know in what is the usage of OnReconnect method which can be overidden in the hub class .

我还需要知道如何处理连接,以防万一 iis 出于任何原因重新启动 Internet 应用程序.

I need also to know how to handle the connection to not being lost in case if the iis restarts the internet application for any reason.

推荐答案

将连接映射到用户可以通过多种方式完成,具体取决于您想要实现的目标:

Mapping connections to users can be done in multiple ways, depending on what you want to achieve:

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

In memory storage:
Best way to do that is by using a concurrent dictionary. This will allow thread safe operations, but, as you said, not the best solution for massive number of connections.

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

Permanent external storage
Keep your mapping in a database.
The good part: the mapping is available across multiple web servers
The bad part: a lot of stress on the database and a lot of cleanup necessary

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

Single-User Groups
Create one group for each user. This is the most simple and practical solution.

优点:
~ 非常易于使用和实施
~ SignalR 足够聪明,可以在断开连接时从组中删除连接
~删除最后一个连接时删除组
~如果使用Identity,可以将唯一的组名存储为声明[1] [2] 并将其放入您的集线器中,例如:

The good part:
~ really easy to use and implement
~ SignalR is smart enough to remove the connection from the group when disconnected
~ groups are deleted when you remove the last connection
~ if you use Identity, you can store the unique group name as a claim [1] [2] and get it inside your hub with something like:

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 将连接添加到组

The (not really that) bad part: you have to be careful with what user joins what group. !DO NOT! implement the join group functionality on the client side. Instead, use OnConnected and OnReconnected to add the connection to the group

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);
}

对于其他问题,您可以阅读以下内容:了解和处理 SignalR 中的连接生命周期事件

For other question, you can read this: Understanding and Handling Connection Lifetime Events in SignalR

这篇关于在 SiganlR 中处理并发连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆