2010-05-12 5 views
5

Ive에 netTcpBinding 및 콜백 메소드를 사용하는 호스트/클라이언트 WCF 서비스 및 클라이언트가 있습니다. 콜백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 메시지의 오류가 발생하지 않습니다.

나는 receiveTimeout이 TCP를 통한 WCF 메시지의 응답이 실패했는지 감지 할 수있는 방법을 제공한다고 생각 했습니까? 연결에 오류가있는 이유는 무엇입니까? 타임 아웃 기간 동안 생성 된 콜백 객체가 없으면 채널이 닫히는 것으로 거의 나타납니다?

내가 뭘 잘못하고 있니?

+0

어떤 해결책이 있습니까? –

답변

2

프록시 생성 (클라이언트)에서 DuplexChannelFactory을 사용해 보셨나요? 여기가 (새로운 AlarmServerClient을 이용하여 생성 (컨텍스트) 교환) 사용되는 방법 : 활성화하여, 채널 통신을 분석

그것의 가능한 : 트레이스를 분석하여 로그 가능 :

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

EDIT 메시지 로깅 및 추적 :

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

이 경우 추적은 "정보"를 기록 할 수 있습니다. 채널을 만드는 것이 중요합니다.

+0

시도해 봤는데 도움이 안된 것 같습니다. 아직도 임박한 임씨 !! – PrimeTSS

+0

필자는 바인딩을 단순화하고 시간 초과 및 reliablesession 속성 <바인딩 이름 = "tcp_Unsecured"> 제거있어 <보안 모드 = "없음"/> 아직도 전화가 다시 채널로 간다 " 오류 "상태 (왜이 오류에 대해 더 알고 싶습니까?) – PrimeTSS

+0

로그를 활성화하면 통신이 충돌하는 위치를 분석 할 수 있습니다. 희망이 도움이됩니다! – Erup

5

이를 보인다 \ 프로그램 파일 \은 Microsoft SDKs \ 윈도우 \ v6.0A \ 빈 \ SvcTraceViewer.exe : 일반적으로 C에서 마이크로 소프트 윈도우 SDK -

는 서비스 추적 뷰어를 사용하여 수 있으며, svclog 파일을 분석하려면 Receivetime out은 콜백 호스트 서비스가 최대 개수에 도달 한 후 오류를 발생시킵니다. 23.59 시간 또는 1 분 기본값입니다. 내가 할 수 는
<bindings> 
     <netTcpBinding> 
     <binding name="NetTcpBinding_AlarmServer" receiveTimeout="infinite" > 
      <security mode="None" />   
     </binding> 
     </netTcpBinding> 
    </bindings> 

을 Infinate을 설정 receivetimeout와 시간 제한 문제를 해결하지만이 메신저 정말 서버/클라이언트 통신에 WFC에 적합한 도구를 사용하는 경우 나 지금 궁금 있습니다. 호스트/서버를 파일 서버에서 실행하고 여러 원격 클라이언트를 연결하려고합니다. 클라이언트는 하트 비트 (heartbeat)로 서버에 ping을 실행하고, 때로는 서버가 클라이언트에 명령을 보낼 수 있습니다. remoting 또는 tcpsockets를 사용하여이 작업을 수행하고 "클라이언트 폴링 방법"을 사용했습니다. 여기서 명령은 데이터베이스에서 quued되고 클라이언트가 명령을 위해 10 분마다 서버를 폴링했을 때 고유 한 클라이언트에 대해 보류중인 명령이있는 경우 그것.클라이언트가 무작위로 연결하고 연결을 끊을 수 있으므로이 작업은 정상적으로 수행되었으며 서버에 1000 개의 TCP 소켓 연결을 사용하지 않는 이점이있었습니다. 그러나 WCF를 시도하기로 결정했는데 (Remoted를 대체하는 새로운 greates 최신 버전은 없습니까?) 듀플렉스를 발견했을 때 이드는 그것을 사용했습니다 .... 지금 WCF Duplux가 무엇인지에 대한 요점을 놓치고 있습니다. ???

도움말 여기에 개념이 누락되어 있습니까?

4

receiveTimeout이 설정된 값은 응용 프로그램 메시지를 수신하지 않을 때 통신 채널에 오류가 발생하기 전에 대기 할 시간을 서비스에 알립니다. 항상이 시간 초과 값을 더 큰 숫자 (기본값은 10 분)로 늘릴 수 있지만 세션 비 활동 시간 초과를 늘려야합니다. 두 시간 초과에 대한 자세한 내용은 http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx을 참조하십시오.

수신 또는 비활성 시간 초과가 발생하면 이중 채널에 오류가 발생합니다. 서버와 다시 통신하려면 클라이언트 측에서 새 프록시를 만들어야합니다.

서버를 호출하기 전에 클라이언트 측에서 채널 연결 상태를 항상 확인할 수 있습니다. 채널의 CommunicationState가 열리지 않은 경우 서버를 호출하기 전에 새 프록시를 만들 수 있습니다.