Выполнение вызовов WCF TimeOut

Я написал систему, которая использует канал Duplex NetTcp с обратным вызовом для работы в качестве сервера публикации/подписки.

Должен ли я беспокоиться о выделении времени обратного вызова, если соединение не будет отправлено через некоторое время или будет ли поддерживаться канал обратного вызова на неопределенный срок?

Ответ 1

Обратный вызов не будет поддерживаться неограниченно, он будет искать значения тайм-аута, которые вы установили в своей конфигурации. Если вы включите надежные сеансы, вы можете установить тайм-ауты бездействия ваших клиентов. Вы можете настроить таймауты следующим образом:

 <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.

EDIT:

Вы можете постоянно менять программный код 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 минуты. Важно отметить, что если вы хотите воссоздать новые прокси-серверы, подобные этому, тогда вам нужно снести старый клиент  прокси и ящик нового, который фактически отключает ваших клиентов от службы, по крайней мере на мгновение.

Также вы можете изменять эти значения (openTimeout, closeTimeout и т.д.) программно на обоих серверах при создании экземпляра нового узла службы. Вы можете создать новый хост, основанный на одной из конфигураций привязки, которые вы определили в своей конфигурации,  или создать новую конфигурацию программно, примерно так:

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. И вы также можете легко создать целую конфигурацию сервиса программно.