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

这是我的Hub代码:

 public class Pusher : Hub, IPusher { readonly IHubContext _hubContext = GlobalHost.ConnectionManager.GetHubContext(); 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; }; }); 

我的问题是什么?

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

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

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

一旦您决定采用哪种方法,通过Pusher集线器发送消息的所有操作都将是:

 // Get the context for the Pusher hub IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext(); // Notify clients in the group hubContext.Clients.Group(group).GetData(data); 

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

从控制器的动作调用hub方法 (不介意标题,它适用于您的场景)

请查看此主题的链接(如何从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 _instance = new Lazy(() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext())); 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); } } }