C# 如何从外部调用 SignalR 集线器方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17534505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I call a SignalR hub method from the outside?
提问by
This is my Hubcode:
这是我的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);
}
}
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.
我想要调用PushToOtherInGroup,调用该方法时我没有收到任何错误。但是推送器不起作用。
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?
我的问题是什么?
采纳答案by Drew Marsh
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.
您不能像那样直接实例化和调用集线器类。SignalR 运行时围绕 Hub 类提供了很多管道,您可以通过将其用作“普通类”来绕过这些管道。
The only way to interact with a SignalR hub from the outside is to actually get an instance of an IHubContextthat 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.
从外部与 SignalR 集线器交互的唯一方法是IHubContext从 SignalR 运行时实际获取代表集线器的 的实例。您只能在同一个进程中执行此操作,因此只要您的其他“项目”将与 SignalR 代码一起在进程中运行,它就会工作。
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.
如果您的其他项目将在另一个进程中运行,那么您想要做的是公开一种“配套”API,它是另一个 SignalR 集线器或常规的旧 Web 服务(使用 ASP.NET Web API)可以从这个其他应用程序调用以触发您想要的行为。无论您选择哪种技术,您都可能希望对其进行保护,以便只有经过身份验证的应用程序才能调用它。
Once you decide which approach you're going to take, all you would do to send messages out via the Pusher hub would be:
一旦您决定要采用哪种方法,通过 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);
回答by N. Taylor Mullen
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)
从控制器的操作中调用集线器方法(不要介意标题,它适用于您的场景)
回答by Rzassar
Take a look at thislink 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 IHubContextinto it's constructor. Then you have access to desired context.Clientsin caller class's methods:
请查看主题中的此链接(如何从 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);
}
}
}

