我有一个WCF服务,我定义了一个名为IsAlive()的操作契约方法。目标是在其回调函数完成之前检查客户端是否仍然存在。
if (IsClientAlive())
WcfService.Callback.UIMessageOnCallback(UIMessage);
默认超时设置为1分钟,在我的情况下太长。由于所有事情都发生在同一个工作站上,我想将其减少到5秒,因此执行只会有一点延迟。
我相应地修改了我的app.config,但之后没有任何改变。 IsAlive()函数持续1分钟完成。 知道我错过了什么吗?
<?xml version="1.0" encoding="utf-8" ?><configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup> <system.serviceModel>
<bindings>
<wsHttpBinding>
<binding openTimeout="00:00:05"
closeTimeout="00:00:05"
sendTimeout="00:00:05"
receiveTimeout="00:01:00">
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="EEAS.Kiosk.WcfService">
<endpoint address="" binding="wsDualHttpBinding" contract="EEAS.Kiosk.IWcfService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/KioskService/WcfService/" />
</baseAddresses>
</host>
</service>
</services> </system.serviceModel></configuration>
注意 :我有一个误导&#34; wsHttpBinding&#34;当它必须是&#34; wsDualHttpBinding&#34;。感谢stuardt的小费!我做了更改,但IsAlive()函数总是抛出异常&#34;会话通道超时&#34;。
{System.ServiceModel.CommunicationObjectAbortedException:操作&#39; IsAlive&#39;无法完成,因为会话通道超时等待接收消息。要增加超时,请在配置文件中的绑定上设置receiveTimeout属性,或者直接在Binding上设置ReceiveTimeout属性。
所以我将ReceiveTimeout超时恢复到1分钟,但错误仍然存在。知道会发生什么吗?我检查了变量host.State,它的值是CommunicationState.Opened。
答案 0 :(得分:0)
这个解释给了我最后的提示。 https://www.rauch.io/2015/06/25/all-wcf-timeouts-explained/
所以我每隔15秒就使用一个计时器在客户端实现心跳。 receiveTimeout设置为1分钟,因此在断开连接之前可能会错过3次心跳。
在客户端的主要方法中:
System.Timers.Timer keepAliveTimer = new System.Timers.Timer(15000);
keepAliveTimer.AutoReset = false;
keepAliveTimer.Elapsed += new System.Timers.ElapsedEventHandler(keepAliveTimer_Elapsed);
keepAliveTimer.Start();
以及在WCF服务中调用isAlive方法的函数。
void keepAliveTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
client.isAlive();
}
catch (System.Exception ex)
{
eventLog1.WriteEntry(" [CRITICAL EXCEPTION in keepAliveTimer_Elapsed()]. WCf service is down, Kiosk Tray Agent is trying to send a heartbeat." + Environment.NewLine + "Caught an exception of type" + ex.GetType().Name, EventLogEntryType.Error, 912);
}
finally
{
((System.Timers.Timer)sender).Start();
}
}