如何从外部调用SignalR集线器方法?

时间:2013-07-08 19:32:43

标签: c# signalr signalr-hub

这是我的Hub代码:

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);
    }
}

我希望使用以下代码在另一个项目中调用此方法:

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

我想调用PushToOtherInGroup,在调用方法时我没有收到任何错误。但是推送器不起作用。

这是我的Ui代码:

$(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;
    };
});

我的问题是什么?

3 个答案:

答案 0 :(得分:22)

您不能直接实例化并直接调用集线器类。 SignalR运行时在Hub类周围提供了很多管道,你可以将它作为一个“普通类”来绕过它。

从外部与SignalR集线器交互的唯一方法是实际从SignalR运行时获取代表集线器的IHubContext实例。您只能在同一个过程中执行此操作,因此只要您的其他“项目”将使用SignalR代码运行,它就可以运行。

如果你的其他项目将在另一个进程中运行,那么你想要做的是暴露一种“伴侣”API,它是另一个SignalR中心或常规的旧Web服务(使用ASP.NET web API)你可以从这个其他应用程序调用来触发你想要的行为。无论您选择哪种技术,您都可能希望确保这一点,以便只有经过身份验证的应用程序才能调用它。

一旦你决定采取哪种方法,你通过Pusher中心发送信息的所有工作都是:

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

// Notify clients in the group
hubContext.Clients.Group(group).GetData(data);

答案 1 :(得分:7)

如果您要从另一个项目调用集线器中的方法,则需要将其驻留在同一个应用程序域中。如果确实如此,你可以这样做:

Call a hub method from a controller's action(不介意标题,它适用于您的场景)

答案 2 :(得分:0)

请查看主题为this链接(如何从Hub类外部调用客户端方法和管理组)。
代码示例只是创建调用者类的单例实例,并将IHubContext传递给它的构造函数。然后,您可以在调用者类的方法中访问所需的context.Clients

// 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);
        }
    }
}