WCF回调超时问题

11

我编写了一个系统,使用双工NetTcp通道和回调函数作为发布/订阅服务器。

如果一段时间内没有发送连接请求,我需要担心回调超时吗?还是回调通道会无限期保持?

1个回答

10

回调函数不会无限期地保持,它将查找您在配置中设置的超时值。如果启用可靠会话,则可以设置客户端的不活动超时时间。您可以按以下方式配置超时时间:

 <netTcpBinding>
    <binding 
             closeTimeout="00:01:00"
             openTimeout="00:01:00" 
             receiveTimeout="00:10:00" 
             sendTimeout="00:01:00"
             transactionFlow="false" 
           ......>
        <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="true" />
    </binding>
  </netTcpBinding>
当这些值被达到并且仍然没有响应时,你的通信渠道会出现故障,需要重新创建客户端代理来消耗服务。 receiveTimeout 的默认值是 10 分钟,因此您可以增加它,但还要确保增加您的 inactivityTimeout,您的 inactivityTimeout 应该大于您的 receiveTimeout
编辑:您可以根据客户端发送回服务器的值编程方式不断更改您的 receiveTimeout,关键是在服务和客户端上保持新的超时值相同。 您可以在客户端执行此操作(我正在使用 WCF 和 Silverlight 客户端制作聊天服务的示例):
//Create different clients dynamically
MyChatServiceClient _client1 = new MyChatServiceClient( "NetTcpBinding_IMyChatService_1");
MyChatServiceClient _client2 = new MyChatServiceClient( "NetTcpBinding_IMyChatService_2");
在客户端配置中:
<!--In your config file, define multiple endpoints/behaviors with different values based on your needs-->
        <bindings>
            <customBinding>
                <binding name="NetTcpBinding_IMyChatService_1" receiveTimeout="00:01:00" ...>
                    <binaryMessageEncoding />
                    <tcpTransport maxReceivedMessageSize="283647" maxBufferSize="283647" />
                </binding>
                <binding name="NetTcpBinding_IMyChatService_2" receiveTimeout="00:22:00" ...>
                    <binaryMessageEncoding />
                    <tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://192.168.1.51:4520/VideoChatServer/"
                binding="customBinding" bindingConfiguration="NetTcpBinding_IMyChatService_1"
                contract="IMyChatService" name="NetTcpBinding_IMyChatService_1" />

          <endpoint address="net.tcp://192.168.1.51:4522/VideoChatServer/"
                binding="customBinding" bindingConfiguration="NetTcpBinding_IMyChatService_2"
                contract="IMyChatService" name="NetTcpBinding_IMyChatService_2" />
        </client>
所以您可以在客户端或服务器上的配置中定义多个终结点或绑定,然后基于应用程序中的任何事件,您可以实例化_clientProxyX来消耗_serviceInstanceX,该实例具有不同的绑定/终结点值, 但与之前的服务实例相同的契约。在上面的示例中,第一个绑定超时时间为1分钟,第二个绑定为2分钟。需要考虑的一个重要点是,如果您希望像这样重新创建新的客户端代理,则需要拆除旧的客户端代理并创建一个新的客户端代理,这会有效地将您的客户端从服务中断开连接,至少瞬间。
此外,您还可以在服务器和客户端上编程方式修改这些值(如openTimeoutcloseTimeout等)。当实例化新的服务主机时,您可以根据在配置中定义的绑定配置之一创建一个新的主机,或者在编程方式下创建一个新的配置,类似于这样:
var host = new ServiceHost(typeof(MyChatService));
            var webHttpBinding = new System.ServiceModel.WebHttpBinding();
            //Modify new timeout values before starting the host
            webHttpBinding.OpenTimeout = new TimeSpan(1, 0, 0);
            webHttpBinding.CloseTimeout = new TimeSpan(1, 0, 0);
            host.AddServiceEndpoint(webHttpBinding, "http://192.168.1.51/myService.svc");
            //start the host after necessary adjustments
            host.Open();

我知道这看起来相当混乱,但重点是WCF使您能够在程序中能够灵活地修改绑定配置。一定要查看这个有关修改WCF配置文件的绝佳答案。而且,您还可以轻松地通过编程方式创建整个服务配置


我想处理定期事件,从服务器每x分钟发送一个“Keep-Alive”消息并将超时设置为2*x,这种做法可行吗? - Omar Kooheji
所以你想根据客户端返回给服务器的内容不断更改receiveTimeout对吗?我以前没做过,但我认为这并不一定是不好的做法。为什么不将超时设置为“无限”呢?你也可以通过编程来实现,像这样:binding.ReceiveTimeout = new TimeSpan(300,0,0,0,0); 这将使你的receiveTimeout为300天。 - Mohammad Sepahvand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接