我设置了一个基于 NetTcpBinding 的 WCF 服务,并且我使用的是 localhost。客户端和主机在同一台机器上运行。我在一段时间内使用 WCF 服务接口的特定方法的客户端出现通信异常。while 循环是强制性的,因为我正在监视一个值,而操作取决于值的变化。客户端是一个 clr 控制台应用程序,包含一个带有服务引用的 dll 和客户端的 app.config 文件。
为了尝试解决这个问题,我在绑定配置中增加了 openTimeout、closeTimeout、receiveTimeout、sendTimeout、maxBufferPoolSize 和 maxReceivedMessageSize,但没有任何成功。
我也让客户端的线程休眠,这样接口的方法调用的频率就少了,也没有任何成功。
为了给你一个想法,你可以在下面找到调用接口方法的客户端的while循环。我还附上了客户端的绑定配置。
While循环:
while (ClientOfIPCService.getUGUDasDouble(ControlUGUD) == ValueOfControlUGUD)
{
Console::WriteLine("Request acProgState...");
CurrentProgStat = ClientOfIPCService.getNCKVariableWithPathasDouble("/Channel/State/acProg[u1,1]");
if (CurrentProgStat == 0 || CurrentProgStat == 3 || CurrentProgStat == 4)
{
exit(0);
}
}
我现在的问题是如何解决这个问题?有没有可能我清空请求的缓冲区?如何避免此通信异常?
2019 年 1 月 8 日更新:
Host的完整App.config文件:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MexGet">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<!--Binding Settings-->
<bindings>
<netTcpBinding>
<binding name="BindingConfig1"
closeTimeout="00:30:00"
openTimeout="00:30:00"
receiveTimeout="00:30:00"
sendTimeout="00:30:00"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxStringContentLength="20000000"
maxArrayLength="20000000"
maxBytesPerRead="20000000"/>
</binding>
</netTcpBinding>
</bindings>
<!--Service Binding-->
<!--2. Configure end point with netTcpBinding-->
<services>
<service behaviorConfiguration="MexGet"
name="PROKOS_IPC_SERVER.HMI_IPC">
<endpoint name="NetTcpBindingEndpoint"
address=""
binding="netTcpBinding"
bindingConfiguration="BindingConfig1"
contract="PROKOS_IPC_SERVER.IHMI_IPC">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<!--3. Configure the meta data exchange end point-->
<endpoint name="MexTcpBidingEndpoint"
address="mex"
binding="mexTcpBinding"
bindingConfiguration=""
contract="IMetadataExchange">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8124/HMI-IPC" />
</baseAddresses>
</host>
</service>
</services>
客户端的完整 App.config 文件:
<system.serviceModel>
<!--Binding Settings-->
<bindings>
<netTcpBinding>
<binding name="BindingConfig1" closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="00:30:00" sendTimeout="00:30:00" maxBufferPoolSize="20000000"
maxReceivedMessageSize="20000000" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8124/HMI-IPC" binding="netTcpBinding"
bindingConfiguration="BindingConfig1" contract="IPC.IHMI_IPC"
name="NetTcpBindingEndpoint">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
在这里,我附上了服务器堆栈跟踪的屏幕截图:
客户端的完整错误消息是:“套接字连接已中止。这可能是由于处理您的消息时出错或远程主机超出接收超时,或底层网络资源问题造成的。本地套接字超时为'00 :29:59.9549975'。”
我没有在客户端处理异常,这在我的 clr 控制台应用程序中给出了以下错误消息。
2019 年 2 月 8 日更新:
以下代码显示了让线程休眠以避免许多请求的想法:
while (ClientOfIPCService.getUGUDasDouble(ControlUGUD) == ValueOfControlUGUD)
{
delay(500);
Console::WriteLine("Request acProgState...");
CurrentProgStat = ClientOfIPCService.getNCKVariableWithPathasDouble("/Channel/State/acProg[u1,1]");
if (CurrentProgStat == 0 || CurrentProgStat == 3 || CurrentProgStat == 4)
{
exit(0);
}
// lets the current thread sleep for X miliseconds
delay(500);
}
另一个想法是集成一种方法,我可以在while循环之后切断电线并再次打开它以供进一步使用。
2019 年 2 月 8 日更新:
我根据需要启用了 WCF 跟踪,并且可以从跟踪中获取以下异常详细信息(请参阅屏幕截图和消息下方的翻译):
“套接字被中止,因为来自套接字的异步接收未在分配的时间限制 00:02:00 内完成。为此任务分配的时间段可能是较长超时的一部分。”