How do I call a SignalR hub method from the outside?
Asked Answered
S

4

20

This is my Hub code:

public class Pusher : Hub, IPusher
{
    readonly IHubContext _hubContext = GlobalHost.ConnectionManager.GetHubContext<Pusher>();

    public virtual Task PushToOtherInGroup(dynamic group, dynamic data)
    {
        return _hubContext.Clients.Group(group).GetData(data);
    }
}

I want call this method in another project with this code:

var pusher = new Pusher.Pusher();
pusher.PushToOtherInGroup("Test", new {exchangeTypeId, price});

I want call PushToOtherInGroup,when calling the method i don't get any error.but pusher does not work.

This is my Ui Code:

$(function() {
    hub = $.connection.pusher;
    $.connection.hub.start()
        .done(function() {
            hub.server.subscribe('newPrice');
            console.log('Now connected, connection ID=' + $.connection.hub.id);
        })
        .fail(function() { console.log('Could not Connect!'); });
});

(function() {
    hub.client.GetData = function (data) {
        debugger;
    };
});

What is my problem?

Synchrotron answered 8/7, 2013 at 19:32 Comment(0)
P
29

You can't instantiate and call a hub class directly like that. There is much plumbing provided around a Hub class by the SignalR runtime that you are bypassing by using it as a "plain-old class" like that.

The only way to interact with a SignalR hub from the outside is to actually get an instance of an IHubContext that represents the hub from the SignalR runtime. You can only do this from within the same process, so as long as your other "project" is going to be running in process with the SignalR code it will work.

If your other project is going to be running in another process then what you would want to do is expose a sort of "companion" API which is either another SignalR hub or a regular old web service (with ASP.NET web API) that you can call from this other application to trigger the behavior you want. Whichever technology you choose, you would probably want to secure this so that only your authenticated applications can call it.

Once you decide which approach you're going to take, all you would do to send messages out via the Pusher hub would be:

// Get the context for the Pusher hub
IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<Pusher>();

// Notify clients in the group
hubContext.Clients.Group(group).GetData(data);
Palindrome answered 9/7, 2013 at 17:35 Comment(1)
Best explanation of how to call/interact with the SignalR runtime from another API. Thanks!Surprint
P
7

If you're looking to call a method in your hub from another project then it needs to reside within the same app domain. If it does here's how you can do it:

Call a hub method from a controller's action (don't mind the title, it works for your scenario)

Piranha answered 9/7, 2013 at 17:32 Comment(0)
G
4

Take a look at this link at the topic of (How to call client methods and manage groups from outside the Hub class).
Code example simply creates a singleton instance of the caller class and pass in the IHubContext into it's constructor. Then you have access to desired context.Clients in caller class's methods:

// This sample only shows code related to getting and using the SignalR context.
public class StockTicker
{
    // Singleton instance
    private readonly static Lazy<StockTicker> _instance = new     Lazy<StockTicker>(() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>()));

private IHubContext _context;

private StockTicker(IHubContext context)
{
    _context = context;
}

// This method is invoked by a Timer object.
private void UpdateStockPrices(object state)
{
    foreach (var stock in _stocks.Values)
    {
        if (TryUpdateStockPrice(stock))
        {
            _context.Clients.All.updateStockPrice(stock);
        }
    }
}
Gristly answered 9/12, 2017 at 8:20 Comment(1)
This should be the accepted answer, especially if working in DotNetCore 3+Basically
O
0

The methods within Hub are supposed to be called FROM a CLIENT. If you want to send something TO a CLIENT - indeed, you have to use hubContext.

Openandshut answered 28/12, 2022 at 15:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.