从系统中的其他位置调用SignalR集线器客户端


71

我已经建立了SignalR集线器以在服务器和客户端之间进行通信。中心服务器端代码存储在名为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()

不幸的是,它不是那么简单,因为客户端不是静态的,因此不能从静态方法访问。

在查看SignalR源代码时,我遇到了一种看似有希望的方法Hubs.Invoke(string hubName, string method, params object[] args),所以我希望可以使用诸如之类的方法,Hubs.Invoke("Hooking", "Test")但不能使其正常工作。

任何帮助将不胜感激


但是也许您可以帮我;)有什么想法如何在广播消息中为所有其他客户端(而不是发出消息的发起方)执行js代码吗?:)
GONeale

不幸的是我没有。我一直在处理此客户端,将客户端ID与响应一起发送回去,并且如果ID匹配则根本不调用该函数
Jordan Wallwork

Answers:


111

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

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

基本上,您可以对当前主机使用依赖项解析器来解析 IConnectionManager接口,接口使您可以获取集线器的上下文对象。

有关更多信息,请参见官方文档


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. 像这样通过依赖注入实例化-

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

2.使用hub这样的对象-

_hub.Clients.All.onBulletinSent(bulletinToSend);

这里可以找到更多。

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


1

看看它是如何在做Chat.csSignalR.Samples.Hubs.Chat,从https://github.com/SignalR/SignalR

我在那里可以看到staticDictionary<TKey, TValue>在顶部被实例化,所以我想它们也将被持久化维护,要么将Chat类作为持久化实例(?),要么以某种方式更新该数组。

检查一下,David Fowler可能是最好的。


是的,我正在使用SignalR示例进行尝试。字典是静态的,因此信息会在该类的多个实例上保留,这就是为什么我希望我可以简单地创建一个Hooking.cs实例并使用它,但是它不起作用
Jordan Wallwork

0

在.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;
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.