![](/img/trans.png)
[英]signalR calls a server method and that method calls a callback method ,outside the hub. How can I call client function from that method?
[英]Calling a server method that is outside of the Hub class from the client in SignalR
考慮下面的類:
using Microsoft.AspNet.SignalR;
public class TwitterStream
{
// Hub Context
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<GeoFeedHub>();
public void ChangeStreamBounds(double latitude, double longitude)
{
Debug.WriteLine(latitude + "-" + longitude);
}
// Lots of other interesting code redacted
}
即使在Hub類之外,也可以從客戶端調用ChangeStreamBounds
方法嗎? 可以從服務器(和Hub類的外部)調用客戶端函數,但是是否可以反過來呢?
不幸的是,我已經陷入困境,必須從我編寫的類中執行代碼(而不是從Hub本身執行-除非您當然可以將SignalR Hub作為Task工廠運行)
您的問題可能涉及HubConnection
和IHubProxy
(可讓您綁定到中心方法調用)或較低級別的API,但我認為您可能會以錯誤的方式進行操作。
從概念上講,您希望GeoFeedHub
處理客戶端請求,並希望TwitterStream
類處理與Twitter API的交互。 因此,您的GeoFeedHub
類具有對TwitterStream
的依賴。
最好您的TwitterStream
類具有async
方法,並且SignalR完全支持此方法。 您可以具有調用TwitterStream
異步Hub方法,從而無需在Global.asax
使用TaskFactory
。
與其在應用程序啟動時創建TwitterStream
並嘗試找到一種將Hub調用綁定到它的方法(向后依賴和違反單一職責原則),不如讓Hub成為實時之間的聯系點,會更干凈客戶端,然后將TwitterStream
實例注入GeoFeedHub
以便集線器可以訪問Twitter API。
下面是一些示例代碼,可以說明這個想法:
public class GeoFeedHub : Hub
{
// Declare dependency on TwitterStream class
private readonly TwitterStream _twitterStream;
// Use constructor injection to get an instance of TwitterStream
public GeoFeedHub(TwitterStream _twitterStream)
{
_twitterStream = _twitterStream;
}
// Clients can call this method, which uses the instance of TwitterStream
public async Task SetStreamBounds(double latitude, double longitude)
{
await _twitterStream.SetStreamBoundsAsync(latitude, longitude);
}
}
public class TwitterStream
{
public TwitterStream()
{
}
public async Task SetStreamBoundsAsync(double latitude, double longitude)
{
// Do something with Twitter here maybe?
await SomeComponent.SetStreamBoundsAsync(latitude, longitude);
}
// More awesome code here
}
我在示例中使用了DI,因此這里是您需要將其連接起來的一些粘合代碼。 此代碼將進入您的App_Start
文件夾:
// Configure Unity as our DI container
public class UnityConfig
{
private static readonly Lazy<IUnityContainer> Container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return Container.Value;
}
private static void RegisterTypes(IUnityContainer container)
{
var twitterService = new TwitterService();
container.RegisterInstance(twitterService);
/*
* Using RegisterInstance effectively makes a Singleton instance of
* the object accessible throughout the application. If you don't need
* (or want) the class to be shared among all clients, then use
* container.RegisterType<TwitterService, TwitterService>();
* which will create a new instance for each client (i.e. each time a Hub
* is created, you'll get a brand new TwitterService object)
*/
}
}
// If you're using ASP.NET, this can be used to set the DependencyResolver for SignalR
// so it uses your configured container
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(UnitySignalRActivator), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(UnitySignalRActivator), "Shutdown")]
public static class UnitySignalRActivator
{
public static void Start()
{
var container = UnityConfig.GetConfiguredContainer();
GlobalHost.DependencyResolver = new SignalRUnityDependencyResolver(container);
}
public static void Shutdown()
{
var container = UnityConfig.GetConfiguredContainer();
container.Dispose();
}
}
public class SignalRUnityDependencyResolver : DefaultDependencyResolver
{
private readonly IUnityContainer _container;
public SignalRUnityDependencyResolver(IUnityContainer container)
{
_container = container;
}
public override object GetService(Type serviceType)
{
return _container.IsRegistered(serviceType)
? _container.Resolve(serviceType)
: base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
return _container.IsRegistered(serviceType)
? _container.ResolveAll(serviceType)
: base.GetServices(serviceType);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.