2010-05-12 21 views
5

Ive ha un servizio WCF host/client e un client che utilizza netTcpBinding e un metodo di callback.WCF, richiamata duplex, 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 esempio

[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); 
} 

cliente con callback

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

Il problema che ho è che dopo la recieveTimeout legame innesca, il cliente entra in uno stato di errore e chiude i clienti ascolto richiama.

È possibile vedere la caduta della porta di ascolto utilizzando TCPVIEW da sysinternals.

Se tengo occupato il canale, il timeout non si attiva, quindi non è un errore nel messaggio WCF al server/client, poiché vari messaggi passano attraverso ok.

Ho pensato che il receiveTimeout è stato progettato per fornire un modo per rilevare se una risposta dal messaggio WCF su TCP non è riuscita? Perché è colpa della connessione. Sembra quasi che se non ci sono oggetti di callback creati per il periodo di timeout, il canale viene quindi chiuso?

Cosa sto sbagliando?

+0

hai trovato qualche soluzione a questo? –

risposta

2

Hai provato a utilizzare una DuplexChannelFactory, nella creazione del proxy (client)? Ecco come viene usata (sostituire la creazione utilizzando nuovo AlarmServerClient (contesto)):

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

EDIT: attivazione di log per analizzare traccia:

sua possibile analizzare la comunicazione canali, abilitando La registrazione dei messaggi e 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 questo caso, la traccia è in grado di registrare "Informazioni". È importante vedere la creazione dei canali.

per analizzare il file svclog, è possibile utilizzare il servizio Trace Viewer - Microsoft Windows SDK, di solito in C: \ Program Files \ Microsoft SDK \ Windows \ v6.0A \ bin \ SvcTraceViewer.exe

+0

Provato, non sembra aiutare. Sono ancora sconcertato !! – PrimeTSS

+0

Ive ha anche semplificato le associazioni e si è liberato dei time out e le proprietà ReliableSession Ancora la chiamata canale posteriore entra in una " Errore "stato (piacere sapere perché e ottenere maggiori informazioni su questo guasto?) – PrimeTSS

+0

Abilitando il registro, è possibile analizzare dove si trova la comunicazione in crash. Spero che sia d'aiuto! – Erup

5

sembra che la Il tempo di ricezione in uscita causa un errore nel servizio host di callback dopo che ha raggiunto il conteggio massimo. Quale è 23.59 ore o il valore predefinito di 1 minuto. posso risolto il problema di timeout con ReceiveTimeout impostazione infinate

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

Ma questo mi ha ora chiedendo se im molto usare lo strumento giusto in WFC per le comunicazioni client/server. Voglio un Host/Server in esecuzione su un file server e più client remoti collegati ad esso. Il client eseguirà il ping del server con un heartbeat e occasionalmente il server potrebbe inviare un comando al client. Lo stavo facendo con remoting o tcpocket e usando un "metodo di polling client", dove i comandi venivano chiusi in un database e quando il client interrogava il server per un comando ogni 10 minuti, se c'era un comando in sospeso per quel client univoco ottenuto esso.Questo ha funzionato bene, e ha avuto il vantaggio di NON avere 1000 connessioni socket TCP aperte sul server, in quanto il client si collegava e si disconnetteva solo in modo casuale. MA ho deciso di provare WCF (dopotutto non è questo il nuovo ultimo di greates che sostituisce Remoting?) E quando ho trovato Duplex ho pensato, Id lo uso .... ORA Sto pensando Mi manca il punto su cosa WCF Duplux è per ???

Aiuto mi mancano i concetti qui ???

4

Il valore a cui è impostato il receiveTimeout indica al servizio il tempo di attesa prima del guasto del canale di comunicazione quando non viene ricevuto alcun messaggio dell'applicazione. È sempre possibile aumentare questo valore di timeout su un numero maggiore (il valore predefinito è 10 minuti), ma è anche necessario aumentare il timeout di inattività della sessione. Si prega di vedere http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx per ulteriori informazioni su entrambi questi timeout.

Quando si attiva il timeout di ricezione o di inattività, il canale duplex è guasto. Dovrai creare un nuovo proxy sul lato client per poter comunicare nuovamente con il server.

È sempre possibile verificare lo stato della connessione del canale sul lato client prima di tentare di chiamare il server. Se CommunicationState del canale non è aperto, è possibile creare un nuovo proxy prima di chiamare il server.

Problemi correlati