J'utilise la fonction 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 bien lorsque vous appelez "Envoyer" via Javascript, mais j'aimerais également que l'application Web publie des messages (à partir d'une méthode d'action ASP.NET MVC). J'ai déjà essayé d'instancier un nouvel objet ob NewsFeedHub et d'appeler la méthode Send, mais cela entraîne une erreur (car la "connexion" sous-jacente du concentrateur n'est pas définie). Existe-t-il un moyen d'utiliser le hub sans connexion?
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 deviennent obsolètes. Cela ne signifie pas qu'ils devraient être rejetés car ils étaient corrects au moment de la rédaction
Il y a une autre réponse mise à jour pour cela, comme vu dans le 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
Mise à jour
Ce code a été mis à jour. Suivez http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server pour les modifications.
Si vous utilisez un conteneur DI
Si vous utilisez un conteneur DI pour câbler vos concentrateurs, récupérez IConnectionManager
à partir de votre conteneur et appelez GetHubContext
sur ce gestionnaire de connexion.
Février 2018, solution courte et simple
Pour résoudre ce problème, je conçois généralement mes hubs 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 à partir du code principal. Les deux méthodes entraînent le même événement chez le client.
mise à jour 2012: Cette réponse est également ancienne! L'API publique de SignalR est en constante évolution, semble-t-il. Tim B James a la nouvelle utilisation correcte de l'API en juillet 2012.
mise à jour 2019 N'utilisez plus cette réponse. Les nouvelles versions de SignalR qui fonctionnent sur AspNetCore devraient faire référence à la réponse acceptée par Tim B James, ou à d'autres réponses votées. Je laisse cette réponse ici pour l'histoire.
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 publier un message sur un concentrateur à 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!");
}
À la suite de la réponse de DDan, vous pouvez créer une méthode statique surchargée et conserver la logique commune dans une seule 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);
}
}
Ensuite, à partir de votre contrôleur, vous pouvez utiliser
Hubs.ChatHub.Send(arg1, null);