背景 我正在创建一个ASP.net应用程序,它使用自定义库(尚未公开发布,但很快)为jQuery中的javascript客户端提供长轮询处理程序。客户端将调用处理程序,等待处理程序返回一些数据,显示它然后再次点击处理程序...清洗,冲洗,重复。
处理程序的工作是接收请求,将其粘贴到一个集合(通常是List<>
)并等待一个事件,其中包含要返回等待请求的数据。我在我的服务器上使用静态类中的一个简单事件对此进行了测试,这一切都正常。
问题 为了让所有客户端收到消息,在我服务器上的所有AppDomain中,我创建了一个简单的C#控制台应用程序 - 它在后台运行并通过WCF(NamedPipe)提供DataContract。然后我在ASP.net中创建了一个客户端对象,它可以通过WCF接口与控制台应用程序通信。
我可以同步拉/推消息到我的缓存中 - 这很好用。但是,当我尝试在WCF契约上使用异步模式时,在我向ImeyncResult返回BeginMethod之后,{I}同时触发EndMethod
。
我看不出有什么问题 - 谷歌有足够的资源显示弱势的例子,他们没有帮助。
我想要什么 他们无论如何通过数据合同绑定到WCF上的事件?这样我就可以加入到事件中并完成它。缓存中的新消息会触发我的事件,触发异步处理程序返回所有等待请求。
这可能,如果有的话,是否有任何样本/教程/示例?
要遵循的代码......
答案 0 :(得分:2)
我知道这是可能的,因为我已经这样做了,并且知道这方面的信息有限(我计划尽快创建博客文章)。基本上,您需要创建Subscribe/Unsubscribe
WCF方法,这将使您的端口保持打开状态。
您的服务器代码应如下所示:
[ServiceContract(SessionMode = SessionMode.Required,
CallbackContract = typeof(IProcessorCallBack))]
public interface IProcessor
{
[OperationContract]
Boolean SubscribeToEvents();
[OperationContract]
Boolean UnsubscribeToEvents();
}
public interface IProcessorCallBack
{
[OperationContract(IsOneWay = true)]
void OnEvent(EventArgs args);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class DDSpeechMikeProcessor:IProcessor
{
private readonly List<IProcessorCallBack> _eventListeners =
new List<IProcessorCallBack>();
public bool SubscribeToEvents()
{
var listenerToCallBacks =
OperationContext.Current.GetCallbackChannel<IProcessorCallBack>();
if(!_eventListeners.Contains(listenerToCallBacks))
_eventListeners.Add(listenerToCallBacks);
}
public bool UnsubscribeToEvents()
{
var listenerToCallBacks =
OperationContext.Current.GetCallbackChannel<IProcessorCallBack>();
if (_eventListeners.Contains(listenerToCallBacks))
_eventListeners.Remove(listenerToCallBacks);
}
//This is your server listening for the main event
//which it will pass on to all listeners
void OnEvent(EventArgs args)
{
foreach(var listener in _eventListeners)
{
try
{
listener.OnEvent(args);
}
catch (Exception exception)
{
RemoveListenerIfBadCommunication(listener, exception);
}
}
}
//If a listener did not unsubscribe before shutting down you will get exceptions
private void RemoveListenerIfBadCommunication(IProcessorCallBack listener,
Exception exception)
{
if (exception.GetType() == typeof(CommunicationException)
|| exception.GetType() == typeof(CommunicationObjectAbortedException)
|| exception.GetType() == typeof(CommunicationObjectFaultedException)
)
_eventListeners.Remove(listener);
}
}
在您的客户端代码中:
public class Client : IProcessorCallBack
{
DuplexChannelFactory<IProcessor> _processorFactory;
IProcessor _processor
void OpenProcessor()
{
_speechMikeProcessorFactory = new DuplexChannelFactory<IProcessor>(
this,
new NetNamedPipeBinding(),
new EndpointAddress(baseUri + @"/" + HostName));
_processor = _speechMikeProcessorFactory.CreateChannel();
_processor.SubscribeToEvents();
}
void OnEvent(EventArgs args)
{
//Do Stuff
}
}
如果我需要更详细地解释任何内容,请告诉我