SignalR + publicar un mensaje a un concentrador a través de un método de acción

Estoy utilizando la función central de SignalR ( https://github.com/SignalR/SignalR ) para publicar mensajes en todos los clientes suscritos:

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

Esto funciona bien cuando llamo “Enviar” a través de Javascript, pero también me gustaría que la aplicación web publique mensajes (desde un método de acción ASP.NET MVC). Ya traté de crear instancias de un nuevo objeto ob NewsFeedHub y llamar al método Send, pero esto da como resultado un error (ya que la “Conexión” subyacente del Hub no está configurada). ¿Hay alguna manera de usar el Hub sin una conexión?

Tenga en cuenta que SignalR API ha cambiado varias veces desde que se hizo esta pregunta. Existe la posibilidad de que algunas respuestas se vuelvan obsoletas. Esto no significa que deberían ser votados negativamente ya que eran correctos en el momento de la escritura

Hay otra respuesta actualizada para esto, como se ve en SignalR Wiki

do#

 Public ActionResult MyControllerMethod() { var context = GlobalHost.ConnectionManager.GetHubContext(); 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 

Actualizar

Este código ha sido actualizado. Siga http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server para ver los cambios.

Si está utilizando un contenedor DI

Si está utilizando un contenedor DI para conectar sus concentradores, obtenga IConnectionManager de su contenedor y llame a GetHubContext en ese connectionManager.

2018 Febrero, solución corta y simple

Para resolver esto, generalmente diseño mis centros de la siguiente manera:

 public class NewsFeedHub : Hub { private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext(); // 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); } } 

Por lo tanto, es fácil llamar desde Javascript y desde el código de back-end también. Los dos métodos están dando como resultado el mismo evento en el cliente.

actualizado : ¡ Esta respuesta también es vieja! La API pública de SignalR está en constante cambio, parece. Tim B James tiene el nuevo y adecuado uso de API a partir de julio de 2012.

La respuesta actualmente aceptada de Mike es antigua y ya no funciona con la última versión de SignalR.

Aquí hay una versión actualizada que muestra cómo publicar un mensaje en un centro desde una acción de controlador MVC:

 public ActionResult MyControllerMethod() { // Important: .Resolve is an extension method inside SignalR.Infrastructure namespace. var connectionManager = AspNetHost.DependencyResolver.Resolve(); var clients = connectionManager.GetClients(); // 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!"); } 

A partir de la respuesta de DDan puede crear un método estático sobrecargado y mantener la lógica común en un método: utilizo este patrón

 public class ChatHub : Hub { private static IHubConnectionContext GetClients(ChatHub chatHub) { if (chatHub == null) return GlobalHost.ConnectionManager.GetHubContext().Clients; else return chatHub.Clients; } // Call from JavaScript public void Send(string message) { Send(message, this); } // Call from C# eg: Hubs.ChatHub.Send(message, null); public static void Send(string message, ChatHub chatHub) { IHubConnectionContext clients = GetClients(chatHub); // common logic goes here clients.All.receiveSend(message); } } 

Luego, desde tu controlador puedes usar

 Hubs.ChatHub.Send(arg1, null);