SignalR +通过操作方法向Hub发送消息

oll*_*ant 64 asp.net-mvc message action signalr signalr-hub

我正在使用SignalR的中心功能(https://github.com/SignalR/SignalR)向所有订阅的客户端发布消息:

public class NewsFeedHub : Hub
public void Send(string channel, string content)
{
    Clients[channel].addMessage(content);
}
Run Code Online (Sandbox Code Playgroud)

这通过Javascript调用"发送"时工作正常,但我也希望Web应用程序发布消息(来自ASP.NET MVC操作方法).我已经尝试实例化新对象ob NewsFeedHub并调用Send方法,但这会导致错误(因为未设置Hub的基础"连接").有没有办法在没有连接的情况下使用Hub?

Tim*_*mes 94

请注意,自提出此问题以来,SignalR API已多次更改.有些答案可能会过时.这并不意味着他们应该在撰写本文时因为正确而被投票

还有另一个更新的答案,如SignalR Wiki所示

C#

Public ActionResult MyControllerMethod()
{
    var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
    context.Clients.All.methodInJavascript("hello world");
    // or
    context.Clients.Group("groupname").methodInJavascript("hello world");
}
Run Code Online (Sandbox Code Playgroud)

vb.net

Public Function MyControllerMethod() As ActionResult
    Dim context = GlobalHost.ConnectionManager.GetHubContext(Of MyHub)()
    context.Clients.All.methodInJavascript("hello world")
    '' or
    context.Clients.Group("groupname").methodInJavascript("hello world")
End Function
Run Code Online (Sandbox Code Playgroud)

更新

此代码已更新.按照http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server更改.

如果您正在使用DI容器

如果您使用DI容器连接集线器,请IConnectionManager从容器中取出,然后调用GetHubContext该connectionManager.

  • *这并不意味着他们应该被否决,因为他们在撰写本文时是正确的*?如果他们不再正确,他们肯定应该被否决吗? (2认同)
  • 理想情况下,标签应具有特定版本的历史准确性。 (2认同)

DDa*_*Dan 55

2018年2月,简短而简单的解决方案

为了解决这个问题,我通常以下列方式设计我的集线器:

public class NewsFeedHub : Hub 
{
    private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NewsFeedHub>();

    // Call this from JS: hub.client.send(channel, content)
    public void Send(string channel, string content)
    {
        Clients.Group(channel).addMessage(content);
    }

    // Call this from C#: NewsFeedHub.Static_Send(channel, content)
    public static void Static_Send(string channel, string content)
    {
        hubContext.Clients.Group(channel).addMessage(content);
    }

}
Run Code Online (Sandbox Code Playgroud)

因此,从Javascript和后端代码调用也很容易.这两种方法在客户端产生相同的事件.

  • 这是我遇到的最好,最有效的解决方案,它是可重复使用的代码,并且工作完美. (2认同)

Jud*_*ngo 10

更新:这个答案也很老了!看来,SignalR的公共API一直在不断变化.截至2012年7月,Tim B James拥有新的,适当的API使用.

Mike目前接受的答案很旧,不再适用于最新版本的SignalR.

这是一个更新版本,显示如何从MVC控制器操作将消息发布到集线器:

public ActionResult MyControllerMethod() 
{
     // Important: .Resolve is an extension method inside SignalR.Infrastructure namespace.
     var connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
     var clients = connectionManager.GetClients<MyHub>();

     // Broadcast to all clients.
     clients.MethodOnTheJavascript("Good news!");

     // Broadcast only to clients in a group.
     clients["someGroupName"].MethodOnTheJavascript("Hello, some group!");

     // Broadcast only to a particular client.
     clients["someConnectionId"].MethodOnTheJavascript("Hello, particular client!");
 } 
Run Code Online (Sandbox Code Playgroud)


Meh*_*ani 7

我正在寻找.NET Core解决方案,谷歌将我发送到这里,似乎没有人提到.NET Core解决方案,所以在这里:

Hub,这里没什么特别的:

public class MyHub : Hub
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在你的里面controller

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

    public HomeController(IHubContext<MyHub> hub)
    {
        _hub = hub;
    }

    public async Task<IActionResult> Index()
    {
        // ...
        await _hub.Clients.All.SendAsync("ReceiveMessage", "Hello from HomeController");
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)