의 클라이언트에서 허브 클래스의 외부에있는 서버 메소드를 호출 수업? 서버 (및 Hub 클래스 외부)에서 클라이언트 함수를 호출 할 수도 있지만 다른 방법으로 수행 할 수 있습니까?아래의 클래스 고려 SignalR
불행히도 필자는 약간의 코너로 돌아 왔고 코드는 필자가 작성한 클래스에서 실행해야합니다 (허브 자체가 아니라 SignalR 허브를 작업 공장으로 실행할 수있는 경우가 아니라면)
의 클라이언트에서 허브 클래스의 외부에있는 서버 메소드를 호출 수업? 서버 (및 Hub 클래스 외부)에서 클라이언트 함수를 호출 할 수도 있지만 다른 방법으로 수행 할 수 있습니까?아래의 클래스 고려 SignalR
불행히도 필자는 약간의 코너로 돌아 왔고 코드는 필자가 작성한 클래스에서 실행해야합니다 (허브 자체가 아니라 SignalR 허브를 작업 공장으로 실행할 수있는 경우가 아니라면)
HubConnection
및 IHubProxy
(허브 메서드 호출에 바인딩 할 수 있음)이나 낮은 수준의 API가 포함되어있을 수 있지만 사용자가 잘못 생각한 것 같습니다.
개념적으로 GeoFeedHub
은 클라이언트 요청을 처리하고 TwitterStream
클래스는 Twitter API와 상호 작용을 처리해야합니다. 따라서 GeoFeedHub
클래스는 TwitterStream
에 종속됩니다.
귀하의 TwitterStream
클래스에는 async
개의 메소드가 있으며이 값은 fully supported in SignalR입니다. TwitterStream
을 호출하는 비동기 허브 메서드를 사용할 수 있으므로 TaskFactory
사용을 Global.asax
에서 제거 할 필요가 없습니다.
응용 프로그램 시작시 TwitterStream
을 만들고 허브 호출을 바인딩하는 방법을 찾는 대신 (뒤로 의존성 및 단일 책임 원칙 위반) 허브를 스탠드 포인트로 삼는 것이 더 깔끔합니다 귀하의 실시간 클라이언트 들간의 접촉, 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);
}
}
고마워요! 좋은 대답 – adaam
왜 거기에서'TwitterStream'의 인스턴스에 다음 전화'ChangeStreamBounds'를 클라이언트에 의해 호출되는 GeoFeedHub''에 방법을 넣어 수 있습니까? –
@RyanErdmann'Global.asax' /'Application_Start'에서'Task.Factory.StartNew (() => new TwitterStream());을 사용하여'TwitterStream' 클래스의 인스턴스를 만들고 있습니다. – adaam
흥미 롭습니다. 'TwitterStream'의 목적은 무엇입니까? 'TwitterStream'은 본질적으로 애플리케이션을위한 싱글 톤 인스턴스입니다. –