我有一个 WCF 服务,我试图让回调工作。
接口类看起来像:
[ServiceContract(
SessionMode = SessionMode.Required,
CallbackContract = typeof(IPredatorEngineCallback))]
public interface IMyApplication
{
[OperationContract]
Boolean DoSomething(string mystring);
[OperationContract]
Boolean SubscribeToEvent();
}
public interface IMyApplicationCallback
{
[OperationContract (IsOneWay = true)]
void EventRaised(EventMessage myEventMessage)
}
EventMessage 是服务器和客户端共享的通信库中的类。
该接口的实现如下所示:
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]
public class MyApplication : IMyApplication
{
private List<IMyApplicationCallback> CallbackList = new List<IMyApplicationCallback>;
public Boolean DoSomething(string mystring)
{
// Do stuff
// Now Raise an event
PublishEvent();
return true;
}
public Boolean SubscribeToEvent()
{
IMyApplicationCallback IMAC = OperationContext.Current.GetCallbackChannel<IMyApplicationCallback>();
if (!Callbacklist.Contains(IMAC)
Callbacklist.Add(IMAC);
}
private void PublishEvent()
{
EventMessage myEM = new EventMessage();
// Populate myEM.Fields
Callbacklist.ForEach(delegate(IMyApplicationCallback callback)
{ callback.EventRaised(myEM); });
}
}
这个想法是客户端可以选择订阅接收事件。
我分阶段构建了我的应用程序,并且在实施回调之前,该服务运行良好。对 DoSomething() 的调用做了他们应该做的事情,并且几乎立即返回。
现在我已经实现了 CallBacks,如果我在 DoSomething 中注释掉 RaiseEvents() 行,它会立即返回。
我的客户端代码现在首先调用 SubscribeToEvent(),然后再调用 DoSomething()。
如果我取消注释并继续使用调试器,我会看到 DoSomething 几乎立即完成 - 没有延迟。我已经在 VS2010 的同一台机器上运行了客户端和 WCF 服务。我一直到 DoSomething() 中的结束 }。
但是,我的客户端中的回调函数没有被调用。1 分钟后,它终于被调用了,而且我还收到一条错误消息,指出我原来的调用已超时。所以我将 app.config 更改为减少到 10 秒,错误消息是:
"This request operation sent to http://localhost:8732/Design_Time_Addresses/MyApplication/MyAppication did not receive a reply in the configured timeout (00:00:09.987997). The time allotted to this operation may have been a portion of a longer timeout..."
因此,似乎有些东西阻止了第一个电话的返回;但该事件已被提出,因为它最终会到达那里。我怀疑这与锁定/并发模式有关,但我承认我迷失了解决方案。
在客户端,我使用了通过添加服务引用生成的代理代码。
服务器端 app.config(仅相关部分):
</configuration>
客户端 App.config:
<configuration>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IPredatorEngine" closeTimeout="00:00:10"
openTimeout="00:00:10" receiveTimeout="00:10:00" sendTimeout="00:00:10"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" />
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8732/Design_Time_Addresses/MyApplication/MyApplication/"
binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IMyApplication"
contract="MyApplication.IMyApplication" name="WSDualHttpBinding_IMyApplication">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
我假设我没有正确配置一些东西。谁能发现它?