2012-05-14 23 views
10

Napisałem system, który używa kanału Duplex NetTcp z funkcją oddzwaniania do funkcji serwera publikowania/subskrypcji.Czy wywołania zwrotne WCF TimeOut

Czy muszę się martwić opóźnieniem oddzwonienia, jeśli połączenie nie zostanie wysłane po pewnym czasie lub czy trasa zwrotna będzie utrzymywana przez czas nieokreślony?

Odpowiedz

10

Oddzwonienie nie zostanie utrzymane przez czas nieokreślony, będzie szukać wartości limitu czasu ustawionych w konfiguracji. Jeśli włączysz niezawodne sesje, możesz ustawić limity czasu bezczynności swoich klientów. limity czasu można skonfigurować tak:

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

Po osiągnięciu tych wartości i nadal nie ma odpowiedzi, kanał komunikacyjny zostaje przerwana i trzeba ponownie utworzyć proxy klienta do konsumpcji usługi. Domyślna wartość dla receiveTimeout wynosi 10 minut, więc możesz ją zwiększyć, ale również zwiększyć swój inactivityTimeout, twój inactivityTimeout powinien być większy niż Twój receiveTimeout.

EDIT:

Można ciągle się zmienia swoją receiveTimeout programowo na podstawie wartości klient wysyła do serwera, kluczowe jest utrzymanie nowych wartości limitu czasu sam na usługi i klienta. Można by zabrać to na kliencie (przykładem Biorę z usługą czatu Robię z WCF i czasochłonne z klientami Silverlight):

//Create different clients dynamically 
MyChatServiceClient _client1 = new MyChatServiceClient("NetTcpBinding_IMyChatService_1"); 
MyChatServiceClient _client2 = new MyChatServiceClient("NetTcpBinding_IMyChatService_2"); 

W konfiguracji klienta:

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

Więc można zdefiniować wiele punktów końcowych lub wiązań w config na klienta lub serwera, a następnie na podstawie jakiegokolwiek zdarzenia w aplikacji można utworzyć wystąpienia _clientProxyX spożywać _serviceInstanceX które mają różne wiązania/końcowego wartości ale sama umowa jako twój poprzednia instancja usługi. W powyższym przykładzie pierwsze wiązanie ma limit czasu wynoszący 1 minutę, a drugie wiązanie trwa 2 minuty. Ważną kwestią, którą należy wziąć pod uwagę, jest to, że jeśli chcesz odtworzyć nowe proxy klientów, to musisz zepsuć starego klienta i zepsuć go, co skutecznie odłączy klientów od usługi, przynajmniej na chwilę.

Można również programowo modyfikować te wartości (openTimeout, closeTimeout) na obu serwerach podczas tworzenia instancji nowego hosta usługi. Można utworzyć nowy gospodarz, oparty na jednym z obowiązującymi konfiguracjach już zdefiniowanych w konfiguracji, lub utworzyć nowy config programowo, coś takiego:

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(); 

To wygląda dość niechlujny wiem, ale chodzi o to, że WCF daje ci dużą elastyczność w możliwości programowej modyfikacji konfiguracji bindowania. Pamiętaj, aby sprawdzić this wspaniałą odpowiedź na modyfikowanie plików konfiguracyjnych WCF. Możesz także łatwo stworzyć cały obiekt service configuration programmtically.

+0

Chcę obsługiwać okresowe zdarzenia, czy dopuszczalne jest, aby wiadomość "Keep-Alive" była wysyłana z serwera co x minut i ustawiała czas na 2 * x? –

+0

Chcesz dalej zmieniać metodę receiveTimeout na podstawie tego, co klient wraca na serwer? Nie robiłem tego wcześniej, ale nie uważam, że musi to być zła praktyka. Dlaczego nie ustawisz limitu czasu na "nieskończony"? Możesz także zrobić programowo w następujący sposób: binding.ReceiveTimeout = new TimeSpan (300,0,0,0,0); to sprawi, że otrzymaszTimeout 300 dni. –

Powiązane problemy