2012-05-14 3 views
10

Ho scritto un sistema che utilizza un canale NetTcp Duplex con un callback per funzionare come server di pubblicazione/sottoscrizione.Do Callbacks WCF Timeout

Devo preoccuparmi del timeout della richiamata se la connessione non viene inviata dopo un po 'o la pipe di callback verrà mantenuta indefinitamente?

risposta

10

Il callback non verrà mantenuto a tempo indeterminato, cercherà i valori di timeout impostati nella configurazione. Se si abilitano sessioni affidabili, è possibile impostare i timeout di inattività dei client. È possibile configurare timeout in questo modo:

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

Dopo aver raggiunto questi valori e non v'è ancora nessuna risposta, il vostro canale di comunicazione viene colpevolizzata ed è necessario ricreare un proxy client per consumare il servizio. Il valore predefinito per receiveTimeout è di 10 minuti, quindi puoi aumentarlo, ma assicurati anche di aumentare il tuo inactivityTimeout, il tuo inactivityTimeout dovrebbe essere maggiore del tuo receiveTimeout.

EDIT:

Si potrebbe continuare a cambiare la tua receiveTimeout di programmazione basato sui valori vostro client invia al server, la chiave è mantenere i nuovi valori di timeout stessa sul servizio e il client. Si potrebbe andare a fare questo sul client (un esempio sto prendendo da un servizio di chat sto facendo con WCF e consumare con i clienti Silverlight):

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

Nella configurazione client:

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

Così si può definire più endpoint o attacchi nella configurazione sul client o server, allora basata su qualunque evento nella vostra applicazione è possibile creare un'istanza _clientProxyX di consumare _serviceInstanceX che avrà diversi vincolante/endpoint valori ma allo stesso appalto come il tuo precedente istanza di servizio. Nell'esempio sopra il primo binding ha un timeout di 1 minuto, il secondo binding 2 minuti. Un punto importante da considerare è che se si desidera ricreare nuovi proxy client come questo, è necessario eliminare il proxy del vecchio client e crearne uno nuovo, che disconnette in modo efficace i client dal servizio, almeno momentaneamente.

Inoltre è possibile modificare tali valori (openTimeout, closeTimeout ecc.) A livello di codice su entrambi i server durante l'istanziazione di un nuovo host di servizio. È possibile creare un nuovo host, sulla base di una delle configurazioni di legame che avete definito nella configurazione, o creare una nuova configurazione a livello di codice, qualcosa di simile:

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

questo appare piuttosto confusa lo so, ma il punto è che WCF ti dà molta flessibilità nel riuscire a modificare le tue configurazioni di binding in modo programmatico. Assicurati di dare un'occhiata this ottima risposta sulla modifica dei tuoi file di configurazione WCF. E puoi anche creare facilmente un intero service configuration programmtically.

+0

Desidero gestire eventi periodici, sarebbe accettabile che un messaggio "Keep-Alive" venga inviato dal server ogni x minuti e impostare il timeout su 2 * x? –

+0

Quindi vuoi continuare a cambiare il receiveTimeout in base a ciò che il tuo client ritorna al server giusto? Non l'ho mai fatto prima, ma non penso che sia necessariamente una cattiva pratica. Perché non imposti i timeout su "infinito"? Si potrebbe anche farlo programmaticamente in questo modo: binding.ReceiveTimeout = new TimeSpan (300,0,0,0,0); questo renderà la tua ricezione entro 300 giorni. –