我正在将服务构建到现有应用程序中,其中构建每个服务的目的是仅由一个客户端使用,并且客户端和服务器设置有双工通信通道。
限制
- 我没有重新设计现有基础设施的选项
- 我无法使用可共享会话
要求:
- 我需要能够在客户端服务之间进行通信(例如,如果用户单击一个项目并想要共享该项目,客户端出于某种原因可能无法处理“共享”功能并需要通过它交给另一个客户处理 - 这必须通过服务完成)
- 客户端之间的通信必须由服务进行。
为了让这个最初工作,我直接在两个客户端之间设置了一个 IPC 通道(netNamedPipeBinding),但我被告知通过服务器发送所有内容。在大多数情况下,这种情况下的“服务器”与客户端在同一台机器上运行,所以我想出了这个非常粗略的概念验证尝试(见下面的代码块)。
问题:当为订阅服务调用方法时,当前服务(在其中调用方法)的操作上下文为空 - 这使服务无法回调客户端
我正在考虑使用 Juval Löwy 在他的 ServiceModelEx 框架中提供的发布/订阅框架,但是当所有客户端已经在他们自己和各自的服务之间建立了双工通信设置时,这似乎是不必要的......所以目的只是添加一个简单的发布/订阅层,概念上位于这些服务“下方”,可以与任何愿意订阅的服务对话。
欢迎提出建议和建设性批评!
public static class SubscriptionManager<TEventArgs>
where TEventArgs : class
{
private static ConcurrentDictionary<int, Action<TEventArgs>> _subscribers =
new ConcurrentDictionary<int, Action<TEventArgs>>();
// sessionId is NOT the WCF SessionId
public static void FireEvent( int sessionId, TEventArgs eventArgs )
{
var subscribers = _subscribers.Where( s => s.Key == sessionId );
var actions = subscribers.Select( keyValuePair => keyValuePair.Value );
foreach ( var action in actions )
action.BeginInvoke( eventArgs, action.EndInvoke, null );
}
public static void Subscribe(int sessionId, Action<TEventArgs> eventHandler)
{
_subscribers.TryAdd(sessionId, eventHandler);
}
public static Action<TEventArgs> Unsubscribe(int sessionId)
{
Action<TEventArgs> eventHandler;
_subscribers.TryRemove(sessionId, out eventHandler);
return eventHandler;
}
}