2010-05-12 7 views
5

Ich habe einen Host/Client-WCF-Dienst und einen Client, der netTcpBinding und eine Callback-Methode verwendet.WCF, Duplex-Rückruf, recieveTimeout netTcpBinding

<bindings> 
     <netTcpBinding> 
     <binding name="tcp_Unsecured" receiveTimeout="00:01:00" sendTimeout="00:01:00"> 
      <security mode="None" /> 
      <reliableSession enabled="true" ordered="true" inactivityTimeout="00:10:00"/> 
     </binding> 
     </netTcpBinding> 
</bindings> 

Proxy

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] 
[System.ServiceModel.ServiceContractAttribute(Namespace="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples", ConfigurationName="AlarmServer", CallbackContract=typeof(AlarmServerCallback), SessionMode=System.ServiceModel.SessionMode.Required)] 
public interface AlarmServer 
{ 

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/RegisterAlarm")] 
    void RegisterAlarm(System.DateTime alarmTime, string clientName, string reminderMessage); 

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/unRegisterAlarm")] 
    void unRegisterAlarm(string clientName); 

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/broadcastMessage")] 
    void broadcastMessage(string msg); 
} 

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] 
public interface AlarmServerCallback 
{ 

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/SignalAlarm")] 
    void SignalAlarm(string reminderMessage); 

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://dotnetaddict.dotnetdevelopersjournal.com/wcf.samples/AlarmServer/displayMessage")] 
    void displayMessage(string msg); 
} 

Client-Instanz mit Rückruf

public MainForm() 
{ 
    InitializeComponent(); 
    InstanceContext context = new InstanceContext(new AlarmCallback()); 
    client = new AlarmServerClient(context); 
} 

Das Problem, das ich habe, ist, dass nach der Bindung recieveTimeout auslöst, geht der Client in einen Fehlerzustand und schließt die Kunden hören Rückrufen.

Ich kann den Listening-Port Drop mit TCPVIEW von Sysinternals sehen.

Wenn ich den Kanal besetzt halte, wird die Zeitüberschreitung nicht ausgelöst, also ist es kein Fehler in der WCF-Nachricht an den Server/Client, da mehrere Nachrichten in Ordnung fließen.

Ich dachte, die receiveTimeout wurde entwickelt, um eine Möglichkeit zu erkennen, ob eine Antwort von der WCF-Nachricht über TCP fehlgeschlagen ist? Warum ist die Verbindung fehlerhaft? Es scheint fast, dass, wenn kein Callback-Objekt für die Timeout-Zeit erstellt wird, der Kanal geschlossen wird?

Was mache ich falsch?

+0

Haben Sie eine Lösung gefunden? –

Antwort

2

Haben Sie versucht, eine DuplexChannelFactory in der Proxy-Erstellung (Client) zu verwenden? Hier ist, wie es verwendet wird (die Erstellung ersetzen mit neuen AlarmServerClient (Kontext)):

AlarmServer proxy = new DuplexChannelFactory<AlarmServer>(context,"YourAlarmServerEndpoint").CreateChannel(); 

EDIT: Protokoll Spur zu analysieren Aktivieren:

Es ist möglich, die Kommunikationskanäle zu analysieren, indem es Nachrichtenprotokollierung und Trace:

<system.diagnostics> 
<sources> 
    <source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing"> 
    <listeners> 
     <add type="System.Diagnostics.DefaultTraceListener" name="Default"> 
     <filter type="" /> 
     </add> 
     <add name="ServiceModelMessageLoggingListener"> 
     <filter type="" /> 
     </add> 
    </listeners> 
    </source> 
    <source name="System.ServiceModel" switchValue="Information,ActivityTracing" 
    propagateActivity="true"> 
    <listeners> 
     <add type="System.Diagnostics.DefaultTraceListener" name="Default"> 
     <filter type="" /> 
     </add> 
     <add name="ServiceModelTraceListener"> 
     <filter type="" /> 
     </add> 
    </listeners> 
    </source> 
</sources> 
<sharedListeners> 
    <add initializeData="Your_svclog_file_here" 
    type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
    name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp"> 
    <filter type="" /> 
    </add> 
    <add initializeData="Your_svclog_file_here" 
    type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
    name="ServiceModelTraceListener" traceOutputOptions="Timestamp"> 
    <filter type="" /> 
    </add> 
</sharedListeners> 
<trace autoflush="true" /> 

In diesem Fall kann der Trace "Informationen" protokollieren. Es ist wichtig, die Erstellung der Kanäle zu sehen.

die svclog Datei zu analysieren, können Sie den Service Trace Viewer können - Microsoft Windows SDK, in der Regel in C: \ Programme \ Microsoft SDKs \ Windows \ V6.0A \ bin \ SvcTraceViewer.exe

+0

Versuchte es, schien nicht zu helfen. Ich bin immer noch verblüfft !! – PrimeTSS

+0

Ive vereinfacht auch die Bindungen und wurde von den Auszeiten befreien und reliablesession Eigenschaften Immer noch der Rückruf-Kanal geht in einen " Fault "state (Liebe, warum zu wissen und erhalten Sie weitere Informationen zu diesem Fehler?) – PrimeTSS

+0

Durch Aktivieren von Protokoll können Sie analysieren, wo die Kommunikation abstürzt. Ich hoffe es hilft! – Erup

5

scheint die Receivetime Out führt dazu, dass der Callback-Host-Service einen Fehler verursacht, nachdem er die maximale Anzahl erreicht hat. Welches ist 23.59 Uhr oder der Standard von 1 Minute. kann ich beschlossen, das Timeout Problem mit der Einstellung receivetimeout

<bindings> 
     <netTcpBinding> 
     <binding name="NetTcpBinding_AlarmServer" receiveTimeout="infinite" > 
      <security mode="None" />   
     </binding> 
     </netTcpBinding> 
    </bindings> 

Aber das hat mich jetzt infinate mich gefragt, ob im wirklich das richtige Werkzeug in WFC für Server/Client-Kommunikation verwendet wird. Ich möchte, dass ein Host/Server auf einem Dateiserver läuft und mehrere Remote-Clients damit verbunden sind. Der Client wird den Server mit einem Heartbeat pingen, und gelegentlich kann der Server einen Befehl an den Client senden. Ich tat dies mit Remoting oder TCP-Sockets und mit einer "Client-Polling-Methode", wo Befehle in einer Datenbank abgerufen und wenn der Client den Server alle 10 Minuten nach einem Befehl abfragen, wenn es einen ausstehenden Befehl für diesen eindeutigen Client gab es.Dies funktionierte in Ordnung und hatte den Vorteil, dass 1000 offene tcp-Socket-Verbindungen zum Server NICHT vorhanden waren, da der Client sich nur zufällig verbinden und trennen würde. ABER ich entschied mich, WCF zu versuchen (schließlich ist das nicht das neue späteste, das Remoting ersetzt?) Und als ich Duplex fand, dachte ich, benutze es .... NOW Im denkend, ich vermisse den Punkt über, was WCF Duplux für ist ???

Hilfe bin ich die Konzepte hier fehlt ???

4

Der Wert, mit dem receiveTimeout festgelegt wird, informiert den Dienst darüber, wie lange gewartet werden muss, bevor der Kommunikationskanal gestört wird, wenn keine Anwendungsnachricht empfangen wird. Sie können diesen Zeitüberschreitungswert immer auf eine größere Anzahl erhöhen (standardmäßig 10 Minuten), Sie müssen dann jedoch das Zeitlimit für die Sitzungsinaktivität erhöhen. Weitere Informationen zu diesen Zeitüberschreitungen finden Sie unter http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx.

Wenn das Empfangs- oder Inaktivitätszeitlimit ausgelöst wird, ist der Duplexkanal gestört. Sie müssen einen neuen Proxy auf der Clientseite erstellen, um erneut mit dem Server kommunizieren zu können.

Sie können den Kanalverbindungsstatus auf der Clientseite immer überprüfen, bevor Sie versuchen, den Server anzurufen. Wenn der CommunicationState des Kanals nicht geöffnet ist, können Sie vor dem Aufruf des Servers einen neuen Proxy erstellen.