【问题标题】:How to get hold of the right SignalR hub in other part of application?如何在应用程序的其他部分获取正确的 SignalR 集线器?
【发布时间】:2020-09-17 00:07:41
【问题描述】:

我正在使用SignalR v2.41,它很旧,但我必须使用它,因为我也仅限于使用旧版本的 MVC。除此之外,我还使用FluentScheduler 定期向客户发送有针对性的消息。

问题是,我在 Hub 中保留了用户连接字典:

public class MyHub: Hub
{
    public Dictionary<string, User> Connections { get; set; }

    public MyHub()
    {
        Connections = new Dictionary<string, User>();
    }

    public override Task OnConnected()
    {
        // add connection
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        // remove connection
        return base.OnDisconnected(stopCalled);
    }
}

现在,在 FluentScheduler 代码中,我需要获取连接列表的集线器,以便知道要向哪个连接发送内容:

public class MyJob : IJob
{
    public void Execute()
    {
        var hub = new DefaultHubManager(GlobalHost.DependencyResolver).ResolveHub("MyHub") as MyHub;
        foreach (var conn in hub.Connections)
        {
            foreach (var msg in msgs)
            {
                hub.Clients.Client(conn.Key).send(msg);
            }
        }
    }
}

问题是,我使用var hub = new DefaultHubManager(GlobalHost.DependencyResolver).ResolveHub("MyHub") as MyHub; 获得的hub 实例与客户端连接的实例不同,因为这个实例从来没有任何连接。

如何获得正确的集线器实例?

【问题讨论】:

    标签: c# asp.net-mvc dependency-injection signalr fluentscheduler


    【解决方案1】:

    new 始终是一个新实例,因此您永远无法获得连接客户端的中心,因为您创建了一个新中心。

    您应该像这样解决集线器:

    static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
    

    您也可以查看question

    编辑:由于您需要向特定用户发送消息,我建议您实现一个类来添加和删除连接,或者更好的是映射users to groups

    建议您始终注入 IHubContext 而不是 Hub。引用来自 github 上的 SignalR 开发人员:

    您通常不应将集线器从 DI 中解析出来。如果您需要在 Hub 和其他组件之间共享代码,我建议您使用 IHubContext 或将共享代码放在单独的 DI 服务中。

    另外,您不应将 Hub 添加为单例:

    SignalR 希望为每条消息单独创建集线器。如果您希望 Hub 处于 DI 中,则需要将其添加为瞬态服务。

    由于 Hub 类的实例是瞬态的,因此您不能使用它们来维护从一个方法调用到下一个方法调用的状态。每次服务器接收到来自客户端的方法调用时,Hub 类的新实例都会处理该消息。要通过多个连接和方法调用来维护状态,请使用其他方法,例如数据库,或者 Hub 类上的静态变量,或者不是从 Hub 派生的不同类。

    更多关于Hub object lifetime的文档。

    【讨论】:

    • 是的,我试过了,但它只给我上下文接口,而不是我的自定义类,它具有Connections 属性。
    • @ColtonScottie 如果您想在代码中发送给所有连接的用户,您需要哪些连接?
    • 这只是一些示例代码,我需要发送给特定用户。这就是我问题的重点。
    • 我已经尝试了几个小时,不幸的是 Autofac 不允许我解析存储连接的对象,因为我没有 HttpContext(在 FluentScheduler 代码中)。好吧,它不是 MVC 的一部分,所以我怎么能...
    • 与注入IHubContext 的方式相同,您将注入连接类并调用返回字典或特定用户连接ID 的方法。
    猜你喜欢
    • 2021-10-06
    • 2022-09-28
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多