2011-09-25 15 views
54

estoy usando la función de hub de SignalR (https://github.com/SignalR/SignalR) para publicar mensajes a todos los clientes suscritos:SignalR + enviar un mensaje a un concentrador a través de un método de acción

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

Esto funciona bien cuando se llama a "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?

+2

se hicieron encuentra la respuesta? estoy en la misma situación. Signalr dll parece inicializar el objeto hub, por lo que me preguntaba si necesitaba acceder a eso. – Mike

Respuesta

79

Tenga en cuenta que la API SignalR ha cambiado varias veces desde que se hizo esta pregunta. Existe la posibilidad de que algunas respuestas se vuelvan obsoletas. Esto no quiere decir que se deben bajar votaron -como lo eran correctos en el momento de escribir

Hay otra respuesta actualizada para esto, como se ve en la 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 

actualización

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 contenedor DI

Si está utilizando un contenedor DI cable hasta sus centros, obtener IConnectionManager de su contenedor, y llamar a GetHubContext en ese ConnectionManager.

+0

¡Funciona muy bien! :) Resolvió mi problema. Estaba teniendo serios problemas con un código que obtuve aquí: http://www.xhroot.com/blog/2012/07/12/live-updates-using-signalr/ –

+0

* Esto no significa que deba ser votaron negativamente ya que estaban correctos en el momento de la escritura *? Seguramente deberían ser votados negativamente si ya no son correctos. – Liam

+0

Lo ideal es que las etiquetas sean específicas de la versión para una precisión histórica. –

8

actualizado: ¡Esta respuesta es vieja también! 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 versión más reciente de SignalR.

Aquí es una versión actualizada que muestra cómo enviar un mensaje a un concentrador de una acción del controlador 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!"); 
} 
+0

Como nota para cualquiera que pruebe esto, parece que estos métodos ya no están disponibles. +1 a Tim para la actualización de la nueva forma. Parece que esto está muy en flujo. –

+0

Estoy confundido. No es 'AspNetHost' parte de 0.4, y no la versión actual (actualmente 0.5.2). Esto no funciona para mí –

+0

¿Has leído la actualización en la parte superior? Esta API también ha sido desaprobada. Por favor, lea la respuesta de Tim B James. –

38

2018 febrero de corto y simple solución

Para la solución de este por lo general diseñar mis cubos de la siguiente manera:

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); 
    } 

} 

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

+1

Agosto de 2016, el único cambio que tuve que hacer fue: Clientes [canal] -> Clientes.Grupo (canal) –

+1

Esta es la mejor y más eficiente solución que he encontrado, es un código reutilizable y funciona perfectamente. –

+0

El método estático no funciona para mí. Lo depuro y lo paso, intenta enviar el JavaScript, pero no pasa nada. El método regular no estático funciona, sin embargo, haciendo exactamente lo mismo. El problema es que no puedo llamarlo desde Web API, lo que intento hacer. Ideas? EDITAR: esto es probablemente horrible, pero en mi método no estático, guardo "Clientes" en una variable privada estática (de IHubConnectionContext ) y luego lo llamo en mi método estático. Funciona, pero ... no se siente bien. – vbullinger

1

A raíz de la respuesta de DDAN puede crear un método estático sobrecargado y mantener la lógica común en un método - Yo uso este patrón

public class ChatHub : Hub 
{ 
    private static IHubConnectionContext<dynamic> GetClients(ChatHub chatHub) 
    { 
     if (chatHub == null) 
      return GlobalHost.ConnectionManager.GetHubContext<ChatHub>().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<dynamic> clients = GetClients(chatHub); 
     // common logic goes here 
     clients.All.receiveSend(message); 
    } 
} 

Luego de su controlador puede utilizar

Hubs.ChatHub.Send(arg1, null); 
Cuestiones relacionadas