SignalR + envoyer un message à un Hub via une méthode d'action
j'utilise la caractéristique hub de SignalR ( https://github.com/SignalR/SignalR ) pour publier des messages à tous les clients abonnés:
public class NewsFeedHub : Hub
public void Send(string channel, string content)
{
Clients[channel].addMessage(content);
}
cela fonctionne très bien quand on appelle "envoyer" via Javascript, mais je voudrais aussi que l'application web publie des messages (de l'intérieur d'un ASP.NET MVC action method). J'ai déjà essayé d'instancier un nouvel objet ob NewsFeedHub et d'appeler la méthode Send, mais cela se traduit par une erreur (comme le sous-jacent "Connexion" de la plate-forme n'est pas définie). Est-il possible d'utiliser le Hub sans connexion?
4 réponses
veuillez noter que L'API SignalR a changé plusieurs fois depuis que cette question a été posée. Il est possible que certaines réponses vont devenir obsolètes. Cela ne signifie pas qu'ils doivent être votés à la baisse car ils étaient corrects au moment de la rédaction de
il y a une autre réponse mise à jour pour ceci, comme vu dans le Wiki SignalR 1519100920"
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
mise à Jour
ce code a été mis à jour. Suivre http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server pour les changements.
si vous utilisez le conteneur DI
si vous utilisez un conteneur DI pour raccorder vos Moyeux, obtenez IConnectionManager
de votre conteneur, et appelez GetHubContext
sur ce connectionManager.
2018 février, Court et simple solution
pour résoudre ce problème, je conçois habituellement mes moyeux de la manière suivante:
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);
}
}
il est donc facile d'appeler à partir de Javascript et du code d'arrière-plan ainsi. Les deux méthodes donnent le même résultat au client.
mise à jour : Cette réponse est vieux, trop! L'API publique de SignalR est en constante évolution, semble-t-il. Tim B James utilise la nouvelle API depuis juillet 2012.
la réponse actuellement acceptée de Mike est ancienne, et ne fonctionne plus avec la dernière version de SignalR.
Voici une version mise à jour qui montre comment poster un message à un hub à partir d'une action de contrôleur 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!");
}
suite à la réponse de Dan, vous pouvez créer une méthode statique surchargée et garder une logique commune dans une méthode - j'utilise ce modèle.""
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);
}
}
puis à partir de votre contrôleur vous pouvez utiliser
Hubs.ChatHub.Send(arg1, null);