从系统其他地方调用SignalR中心客户端

73

我已经设置了一个SignalR hub,用于服务器和客户端之间的通信。Hub服务器端代码存储在名为Hooking.cs的类中。我想要的是能够调用在Hooking.cs中定义的方法,以便从我的应用程序的任何位置广播消息给任何连接的客户端。似乎每个客户端/服务器调用都会创建一个Hooking.cs的新实例,因此我希望我可以使用类似于下面这样的东西:

var hooking = new Hooking();
hooking.Test();

使用在Hooking.cs中定义的Test()方法,如下所示:

public static void Test() {
    Clients.test()
}

同时使用客户端JavaScript

var hooking = $.connection.hooking;
hooking.test = function() { alert("test worked"); };
$.connection.hub.start()
很遗憾,这并不简单,因为Clients不是静态的,所以无法从静态方法中访问。浏览SignalR源代码时,我找到了一个看起来很有希望的方法,Hubs.Invoke(string hubName, string method, params object[] args),所以我希望我可以使用类似Hubs.Invoke("Hooking", "Test")的东西,但我无法使其工作。如果有任何帮助,将不胜感激。

但也许你可以帮我 ;) 有没有什么办法可以在广播消息中执行您的 js 代码,而不是发出消息的原始呼叫方? :) - GONeale
很遗憾,我没有。我一直在处理客户端,将客户端ID与响应一起发送回来,如果ID匹配,则不调用该函数。 - Jordan Wallwork
5个回答

111

这是 SignalR 2.x 的正确方式:

var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.addMessage(message);

基本上,你可以使用当前主机的依赖解析器来解析 IConnectionManager 接口,从而允许你获取一个 hub 的上下文对象。

更多信息可以在 官方文档 中找到。


23

Hub.GetClients在0.4.0版本中已经消失。

wiki中可以看到,现在你可以使用:

IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connectionManager.GetClients<MyHub>();

7
不要忘记添加 using SignalR.Infrastructure; - nmat

6
你可以按照以下2个步骤轻松使用集线器 -
  1. Instantiating by dependency injection like this-

    public class ClassName
    {
        ........
        ........
        private IHubContext _hub;
    
        public BulletinSenderController(IConnectionManager connectionManager)
        {
            _hub = connectionManager.GetHubContext<McpHub>();
            ........
            ........
        }
    
        ............
        ............
    }
    

2. 使用以下方式使用hub对象-

_hub.Clients.All.onBulletinSent(bulletinToSend);

更多相关内容请参见这里

示例代码可以在此 git 仓库中找到。


1

看看在 https://github.com/SignalR/SignalRSignalR.Samples.Hubs.Chat 中的 Chat.cs 是如何实现的。

我可以看到静态的 Dictionary<TKey, TValue> 在顶部被实例化,所以我想它们也被持久地维护着,可能是通过 Chat 类作为一个持久化实例(?)或者那个数组被某种方式更新。

去看看吧,David Fowler 可能是最擅长这个的。


是的,我正在使用SignalR示例来尝试解决这个问题。这些字典是静态的,因此信息会在类的多个实例之间持久存在,这就是为什么我希望可以简单地创建Hooking.cs的一个实例并使用它,但它不起作用。 - Jordan Wallwork

1
在.NET Core 2中,这一点已经改变了,现在您可以像这样使用依赖注入:
    private readonly IHubContext<MyHub,IMyHubInterface> _hubContext;

    public MyController(MyHub,IMyHubInterface hubContext)
    {
        _hubContext = hubContext;
    }

    public bool SendViaSignalR()
    {
        _hubContext.Clients.All.MyClientSideSignalRMethod(new MyModel());
        return true;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接