2012-05-14 11 views
10

Ich habe ein System geschrieben, das einen Duplex NetTcp Channel mit einem Callback verwendet, um als Publish/Subscribe Server zu arbeiten.Do WCF Callbacks TimeOut

Muss ich mir Sorgen machen, dass das Callback-Timing abgelaufen ist, wenn nach einiger Zeit keine Verbindung mehr gesendet wird oder wird die Callback-Pipe auf unbestimmte Zeit beibehalten?

Antwort

10

Der Rückruf wird nicht auf unbestimmte Zeit beibehalten. Er sucht nach den Zeitüberschreitungswerten, die Sie in Ihrer Konfiguration festgelegt haben. Wenn Sie zuverlässige Sitzungen aktivieren, können Sie die Inaktivitätszeitlimits Ihrer Clients festlegen. Sie können Timeouts wie folgt konfiguriert werden:

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

Wenn diese Werte erreicht werden, und es gibt immer noch keine Antwort, Ihr Kommunikationskanal bemängelt wird, und Sie müssen eine Client-Proxy neu erstellen, den Dienst zu verbrauchen. Der Standardwert für receiveTimeout ist 10 Minuten, also können Sie das erhöhen, aber stellen Sie auch sicher, Ihre inactivityTimeout ebenso zu erhöhen, sollte Ihre inactivityTimeout größer sein als Ihre receiveTimeout.

EDIT:

Sie halten könnten Ihre receiveTimeout programmatisch basierend auf Werten Ihr Client ändern an den Server sendet, wird der Schlüssel, um die neuen Timeout-Werte gleicht auf den Service und Client zu halten. Sie würden gehen über das tut dies auf dem Client (ein Beispiel, das ich von einem Chat-Dienst nehme ich mache mit WCF und Konsumieren mit Silverlight-Clients):

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

In der Client-Konfiguration:

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

So können Sie mehrere Endpunkte oder Bindungen in der Config auf dem Client oder dem Server definieren, dann gleich aus welchem ​​ Ereignis in Ihrer Anwendung Sie _clientProxyX instanziieren _serviceInstanceX zu konsumieren, die unterschiedliche Bindungs ​​/ Endpunkt haben Werte aber der gleiche Vertrag als deine vorherige Dienstinstanz. Im obigen Beispiel hat die erste Bindung einen Timeout von 1 Minute, die zweite Bindung 2 Minuten. Ein wichtiger Punkt zu beachten ist, dass, wenn Sie neue Client-Proxies wie diese neu erstellen möchten, müssen Sie Ihren alten Client Proxy abbrechen und eine neue, die effektiv trennt Ihre Clients von dem Dienst, zumindest für einen Moment.

Sie können diese Werte (openTimeout, closeTimeout usw.) auch programmatisch auf beiden Servern ändern, wenn Sie einen neuen Service-Host instanziieren. Sie können einen neuen Host erstellen, basierend auf einer der Bindungskonfigurationen Sie in Ihrer Konfigurations definiert haben, oder eine neue Konfiguration erstellen so etwas wie dies programmatisch:

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

Diese ziemlich chaotisch aussieht weiß ich, aber Der Punkt ist, dass WCF Ihnen eine Menge Flexibilität bietet, wenn Sie Ihre verbindlichen Konfigurationen programmgesteuert ändern können. Achten Sie darauf, this große Antwort auf die Änderung Ihrer WCF-Konfigurationsdateien. Und Sie können auch einfach eine ganze service configuration programmtically erstellen.

+0

Ich möchte mit periodischen Ereignissen umgehen, wäre es akzeptabel, wenn alle x Minuten eine "Keep-Alive" -Meldung vom Server kommt und die Zeit auf 2 * x gesetzt wird? –

+0

Sie möchten also das receiveTimeout basierend auf dem ändern, was Ihr Client an den Server zurückgibt, ändern? Ich habe es noch nie gemacht, aber ich halte es nicht für eine schlechte Übung. Warum stellen Sie die Timeouts nicht einfach auf "unendlich" ein? Sie könnten das auch programmgesteuert so machen: binding.ReceiveTimeout = new TimeSpan (300,0,0,0,0); Dies wird Ihre ReceiveTimeout 300 Tage machen. –