2012-05-14 3 views
10

Я написал систему, которая использует Дуплексный канал NetTcp с обратным вызовом для работы в качестве сервера публикации/подписки.Do WCF Callbacks TimeOut

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

ответ

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.

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 дает вам большую гибкость в том, что вы можете модифицировать программные привязки. Обязательно проверьте this отличный ответ на изменение ваших конфигурационных файлов WCF. И вы также можете легко создать целое service configuration programmtically.

+0

Я хочу обрабатывать периодические события, было бы приемлемой практикой, чтобы сообщение «Keep-Alive» поступало с сервера каждые x минут и устанавливало время на 2 * x? –

+0

Итак, вы хотите продолжать изменять getTimeout на основе того, что ваш клиент вернется на сервер? Я не делал этого раньше, но я не думаю, что это была плохая практика. Почему бы вам просто не установить тайм-ауты на «бесконечный»? Вы также можете сделать это программно следующим образом: binding.ReceiveTimeout = new TimeSpan (300,0,0,0,0); это сделает ваш приемTimeout 300 дней. –