2010-05-12 98 views
5

我有一個主機/客戶端WCF服務和客戶端使用netTcpBinding和回調方法。WCF,雙工回調,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> 

代理與回調

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

客戶端實例

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

我的問題是,結合recieveTimeout觸發後,客戶端進入故障狀態,並關閉客戶端監聽回電話。

我可以從sysinternals中使用TCPVIEW看到偵聽端口丟棄。

如果我保持通道忙,超時不會觸發,所以它不會在WCF消息中發送到服務器/客戶端的故障,因爲多條消息將流經OK。

我認爲receiveTimeout的目的是提供一種方法來檢測通過TCP WCF消息的答覆失敗? 爲什麼它斷開連接。 幾乎看起來,如果在超時期限內沒有創建回調對象,那麼通道會關閉?

我在做什麼錯?

+0

你有沒有找到解決辦法? – 2013-10-14 04:11:53

回答

2

您是否嘗試過在代理創建(客戶端)中使用DuplexChannelFactory? 這裏是如何使用它(更換使用新AlarmServerClient(上下文)創建):

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

編輯:啓用日誌來分析跟蹤:

它可以分析渠道的溝通,通過啓用消息記錄和跟蹤:

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

在這種情況下,Trace可以記錄「信息」。重要的是看到渠道的創造。

要分析svclog文件,你可以使用服務跟蹤查看器 - 微軟的Windows SDK,一般在C:\ Program Files文件\微軟的SDK \的Windows \ v6.0A \ BIN \ SvcTraceViewer.exe

+0

試過了,似乎沒有幫助。 我仍然困惑! – PrimeTSS 2010-05-13 12:57:53

+0

伊夫也簡化了綁定和擺脫了超時和的ReliableSession性質 <綁定名稱=「tcp_Unsecured」> 的<安全模式=「無」 /> 仍然回叫信道進入一個「故障「狀態(愛知道爲什麼,並獲得有關此故障的更多信息?) – PrimeTSS 2010-05-13 13:00:43

+0

通過啓用日誌,可以分析通信崩潰的位置。希望能幫助到你! – Erup 2010-05-13 13:38:14

5

似乎接收超時會導致回調主機服務在達到最大計數後發生故障。即23.59小時或默認1分鐘。 我可以解決超時問題設置有向receivetimeout Infinate

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

,但是現在已經IM是否真的使用正確的工具WFC的服務器/客戶機通訊我想知道。我希望主機/服務器在文件服務器上運行,並且有多個遠程客戶機連接到它。客戶端會使用心跳線ping服務器,偶爾服務器可能會向客戶端發送命令。我正在使用遠程或tcpsockets並使用「客戶端輪詢方法」來執行此操作,其中在數據庫中執行的命令以及客戶端每隔10分鐘對服務器進行一次命令輪詢時,如果存在針對該唯一客戶端的掛起命令它。這工作正常,並且有優點是沒有1000個開放的tcp套接字連接到服務器,因爲客戶端只能隨機連接和斷開連接。 但我決定嘗試WCF(畢竟這不是最新的greates取代遠程?),當我發現雙工我認爲,Id使用它.... 現在我想我缺少關於WCF Duplux是什麼的觀點???

幫助我錯過這裏的概念?

4

設置receiveTimeout的值將告訴服務器在未收到應用程序消息時斷開通信通道之前等待的時間。您始終可以將此超時值增加到更大的值(默認值爲10分鐘),但您還必須增加會話不活動超時值。有關這兩個超時的更多信息,請參見http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx

當接收或不活動超時激活時,雙工通道出現故障。您將不得不在客戶端創建一個新代理,以便能夠再次與服務器進行通信。

在嘗試呼叫服務器之前,您可以隨時檢查客戶端的通道連接狀態。如果通道的CommunicationState未打開,則可以在調用服務器之前創建新的代理。