asp.net mvc - net - SignalR+publicar un mensaje a un concentrador a través de un método de acción
signalr tutorial (4)
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<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, desde tu controlador puedes usar
Hubs.ChatHub.Send(arg1, null);
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?
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<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);
}
}
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.
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<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
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.
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<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!");
}