![](/img/trans.png)
[英]Silverlight client consuming WCF service throws System.ServiceModel.CommunicationException
[英]WCF Service - Client receiving CommunicationException after many requests to localhost
我设置了一个基于NetTcpBinding的WCF服务,并且正在使用localhost。 客户端和主机在同一台计算机上运行。 在while循环中,使用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);
}
}
我现在的问题是如何解决这个问题? 我是否有可能清空请求的缓冲区? 如何避免这种通信异常?
更新01/08/2019:
主机的完整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控制台应用程序中给我以下错误消息。
更新02/08/2019:
以下代码显示了让线程休眠以避免许多请求的想法:
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循环后切断导线,然后再次打开以进一步使用。
更新02/08/2019:
我根据需要启用了WCF跟踪,并且可以从跟踪中获取以下异常详细信息(请参阅消息的屏幕截图和下面的翻译):
“套接字被中止,因为从套接字的异步接收未在分配的时间限制00:02:00内完成。为此任务分配的时间段可能是更长超时的一部分。”
错误的详细信息是什么?
由于默认情况下Nettcpbinding使用消息安全模式和Windows帐户作为客户端凭据,因此尽管服务器和客户端在同一台计算机上,我们仍应在客户端上提供Windows凭据。
此外,请在配置文件中发布完整的System.servicemodel部分。 如果要修改配置,请优先修改服务器的绑定配置。
随时让我知道问题是否仍然存在。
已更新 。
我建议您将Nettcpbinding的安全模式明确指定为NONE 。
<bindings>
<netTcpBinding>
<binding name="willbeappliedontheendpoint">
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
同时删除不相关的配置。
然后我怀疑该连接可能未正确关闭,请尝试在退出前手动在循环内关闭通信连接。
此外,我们还可以尝试使用ChannelFactory封装调用服务的函数。
https://docs.microsoft.com/zh-cn/dotnet/api/system.servicemodel.channelfactory-1?view=netframework-4.8
最后,请参考下面的链接,希望它会有用。
套接字连接已中止-CommunicationException
我设法解决了这个问题。 以下是我的问题和解决方案的简短总结。
问题总结:我创建了一个WCF服务,该服务配置为nettcpbinding。 我有一个包含dll的客户端,该客户端被构建为clr控制台应用程序(dll包含客户端的app.config和使用添加服务引用创建的客户端代理)。 客户端具有带while循环的功能,该功能通过服务请求值。 随着客户端的长时间运行,我的服务抛出了通信异常。
问题的解决方案:我使用svcUtil.exe创建了一个新的代理,其中包含用于关闭和打开通道的方法。 因此,在函数中,我创建了客户端类的新实例,并在函数的开头和结尾打开和关闭通道。 此外,为了不向服务发出太多请求,我让线程在while循环中休眠。
在主函数之后,我还创建了一个新实例以供进一步的请求。 这解决了我的问题。 我的客户端中的函数代码如下所示:
while (myClient.getUGUDasDouble(ControlUGUD) == ValueOfControlUGUD)
{
delay(500);
//Console::WriteLine("Request acProgState...");
CurrentProgStat = myClient.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);
}
if (myClient.getUGUDasDouble(ControlUGUD) == 2)
{
myClient.setUGUDasDouble(ControlUGUD, -1);
}
else
{
MessageBox(0, (LPCWSTR)L"Error :::: IPC Communication Control: Function WaitTillNCFinishedTheJob() :::: Failure: NC needed to write MTU_G_C_NC = 2!", (LPCWSTR)L"Error", MB_ICONWARNING | MB_OK);
exit(0);
}
myClient.Close();
Console::WriteLine("Communication state: " + myClient.State.ToString());
由于我是WCF的新手,因此这种方法对我有效,并解决了我的问题。 针对此问题的回调事件可能是一种更好的方法(请参阅链接)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.