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?

55
demandé sur Ashley Medway 2011-09-26 02:57:44

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.

83
répondu Tim B James 2017-01-06 12:10:52

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.

43
répondu DDan 2018-02-22 04:49:44

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!");
 } 
8
répondu Judah Himango 2012-07-12 07:50:10

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);
1
répondu J45 2017-05-16 09:52:55