18

这是我的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,当调用该方法时我没有收到任何错误。但是推送器不起作用。

这是我的用户界面代码:

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

我的问题是什么?

4

3 回答 3

26

您不能像那样直接实例化和调用集线器类。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);
于 2013-07-09T17:35:02.977 回答
7

如果您希望从另一个项目调用集线器中的方法,那么它需要驻留在同一个应用程序域中。如果是这样,你可以这样做:

从控制器的操作中调用集线器方法(不要介意标题,它适用于您的场景)

于 2013-07-09T17:32:12.187 回答
3

查看链接的主题(如何从 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);
        }
    }
}
于 2017-12-09T08:20:50.837 回答