向所有客户端发送来自服务器的 SignalR 消息

7

这与通过操作方法向Hub发布消息的SignalR相关,但我的问题有所不同:

我使用版本为0.5.2的signalr,使用hubs。在旧版本中,您被鼓励在hub上创建方法以向所有客户端发送消息,这就是我所拥有的:

public class MyHub : Hub
{
    public void SendMessage(string message)
    {
        // Any other logic here
        Clients.messageRecieved(message);
    }

    ...
}

在0.5.2中,我想从控制器的某个位置向所有客户端发送消息。我如何访问MyHub实例?
我见过的唯一方法是:
var hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
hubContext.Clients.messageRecieved("hello");

这很好,但我想在我的信号中心上调用该方法。


现在在ASP.NET Core中也可以实现这一点(尽管SignalR本身仍处于alpha版本)。请参阅此问题的Core版本的详细答案 - brichins
3个回答

20

您可以通过使用静态方法来实现此目的:

SignalR v.04-

public class MyHub : Hub
{
    internal static void SendMessage(string message)
    {
        var connectionManager = (IConnectionManager)AspNetHost.DependencyResolver.GetService(typeof(IConnectionManager));
        dynamic allClients = connectionManager.GetClients<MyHub>();
        allClients.messageRecieved(message);
    }

    ...
}

SignalR 0.5+

public class MyHub : Hub
{
    internal static void SendMessage(string message)
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
        context.Clients.messageRecieved(message);
    }

    ...
}

你可以这样调用:

MyHub.SendMessage("The Message!");

这篇文章介绍了SignalR API的优点:http://weblogs.asp.net/davidfowler/archive/2012/05/04/api-improvements-made-in-signalr-0-5.aspx

由Paolo Moretti在评论中提供。


1
在SignalR 0.5+中,AspNetHost.DependencyResolver已经消失。请参见此处(在连接或Hub之外获取对连接/Hub的引用):http://weblogs.asp.net/davidfowler/archive/2012/05/04/api-improvements-made-in-signalr-0-5.aspx - Paolo Moretti

4

我遇到了同样的问题,在我的例子中,addNotification是客户端方法:

var hubContext = GlobalHost.ConnectionManager.GetHubContext<SignalR.NotificationsHub>();
hubContext.Clients.addNotification("Text here");

在客户端,您可以添加代码在 addNotification 中调用您的 hub 方法:
var notification = $.connection.notificationHub;
notification.addNotification = function (message) {
 notification.addServerNotification(message); // Server Side method
}

$.connection.hub.start();

中继器:

 [HubName("notificationHub")]
    public class NotificationsHub : Hub
    {
        public void addServerNotification(string message)
        {
          //do your thing
        }
    }

更新: 反复阅读您的问题后,我实际上找不到理由这样做。Hub方法通常用于从客户端调用,或者我误解了您的意思,无论如何,这里是一个更新。如果您想在服务器端执行某些操作,然后通知客户端。

  [HttpPost]
  [Authorize]
  public ActionResult Add(Item item)
  {
      MyHubMethodCopy(item);
      var hubContext = GlobalHost.ConnectionManager.GetHubContext<SignalR.NotificationsHub>();
    hubContext.Clients.addNotification("Items were added");

  }

  private void MyHubMethodCopy(Item item)
  {
      itemService.AddItem(item);
  }

另一个回答解答了我的问题,但是考虑后,我不确定是否需要调用 hub 方法 - 就像你所说的“hub方法是供客户端使用的”。您会得到+1的好评。 - Matt Roberts
+1 指出如何使用 hub 方法。我本来也会犯同样的错误,看了之后解决了。 - emre nevayeshirazi
@emrenevayeshirazi 哪里出错了? - yakya

2

ASP.NET Core 2.x和3.x更新:

您可以在任何具有依赖注入的地方轻松访问Hub实例:

public class HomeController : Controller
{
    private readonly IHubContext<MyHub> _myHubContext;

    public HomeController(IHubContext<MyHub> myHubContext)
    {
        _myHubContext = myHubContext;
    }

    public void SendMessage(string msg)
    {
        _myHubContext.Clients.All.SendAsync("MessageFromServer", msg);
    }
}

如果出现语法错误,请确保您已经:
using Microsoft.AspNetCore.SignalR;

并且您没有以下情况

using Microsoft.AspNet.SignalR;

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