SignalR + posting a message to a Hub via an action method
2018 February, Short and simple solution
For solving this I usually design my hubs in the following way:
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);
}
}
So it's easy to call from Javascript and from back-end code as well. The two methods are resulting in the same event at the client.
update 2012: This answer is old, too! SignalR's public API is in constant flux, it seems. Tim B James has the new, proper API usage as of July 2012.
update 2019 Don't use this answer anymore. New versions of SignalR that work on AspNetCore should refer to the accepted answer by Tim B James, or other up-voted answers. I'm leaving this answer here for history's sake.
The currently accepted answer from Mike is old, and no longer works with the latest version of SignalR.
Here's an updated version that shows how to post a message to a hub from an MVC controller action:
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!");
}
I was looking for .NET Core
solution and Google sent me here, seems like no one mentioned .NET Core
solution, so here you go:
The Hub, nothing fancy here:
public class MyHub : Hub
{
// ...
}
Inside your controller
:
public class HomeController : Controller
{
readonly IHubContext<MyHub> _hub;
public HomeController(IHubContext<MyHub> hub)
{
_hub = hub;
}
public IActionResult Index()
{
// ...
await _hub.Clients.All.SendAsync("ReceiveMessage", "Hello from HomeController");
// ...
}
}
Please note that the SignalR API has changed multiple times since this question was asked. There is a chance that some answers will become out of date. This does not mean that they should be down-voted as they were correct at the time of writing
There is another updated answer for this, as seen in the 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");
}
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
Update
This code has been updated. Follow http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server for changes.
If you are using DI container
If you are using a DI container to wire up your hubs, get IConnectionManager
from your container, and call GetHubContext
on that connectionManager.