如何从外部调用SignalR的hub方法?

20

这是我的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;
    };
});

我的问题是什么?

4个回答

29

不能直接实例化和调用一个 Hub 类。使用它作为“普通类”会绕过 SignalR 运行时提供的大量管道操作。

与 SignalR Hub 进行交互的唯一方法是从 SignalR 运行时获取表示该 Hub 的 IHubContext 实例。只能在同一进程内执行此操作,因此只要您的其他“项目”将在与 SignalR 代码相同的进程中运行,它就可行。

如果您的其他项目将在另一个进程中运行,则需要公开某种“伴侣”API,即另一个 SignalR Hub 或常规旧网络服务(使用 ASP.NET Web API),以便您可以从该应用程序调用以触发所需的行为。无论选择哪种技术,都应该对其进行安全保护,以便只有经过身份验证的应用程序才能调用它。

一旦决定采取哪种方法,通过 Pusher Hub 发送消息的所有操作都将是:

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

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

如何从另一个API调用/交互SignalR运行时的最佳解释。谢谢! - Jonathan Counihan

7
如果您想从另一个项目中调用您的hub方法,则它需要驻留在同一个应用程序域中。如果满足此条件,则可以按照以下步骤进行操作:调用控制器操作中的Hub方法(不要介意标题,它适用于您的情况)。

4
请看(如何从Hub类外部调用客户端方法和管理组)主题下的this链接。
代码示例只需创建调用程序类的单例实例,并将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);
        }
    }
}

2
这应该是被接受的答案,尤其是在 DotNetCore 3+ 中工作时。 - Piotr Kula

0

Hub 中的方法应该从客户端调用。 如果您想向客户端发送信息,确实需要使用 hubContext


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接