2012-11-28 2 views
1

최근에 WCF 서비스에서 처리하는 요청/응답을 기록하는 방법을 모색하고있었습니다.WCF 메시지 관리자가 작동하지 않습니다.

이전에는 추적 옵션이 좋지 않았습니다. 요즘에는 실제 응답 및 추적 요청을받는 방법을 아직 모릅니다 (svctraceviewer 도구를 사용해 보았지만 의미있는 결과를 얻지 못했습니다). 그리고 심지어, 추적 파일이 손상되어 생성됩니다 (일부 unexpectable chars 포함).

약 3 ~ 4 일 전에 메시지 검사자 기술에 대해 알아 냈습니다. 나는 this manual을 읽고 다른 프로젝트에서 클라이언트 쪽 메시지 관리자를 구현했습니다. 사실 내 wcf 클라이언트가 보낸 요청과 그 요청에 대한 다른 쪽 서비스 응답을 볼 수있었습니다.

다른 사이드 로깅 (예 : 클라이언트의 서비스 요청 및 서버 응답 받기)이 쉽기를 바랍니다. 하지만 나는 냉담하지 않다. 여기 입니다 세부 정보 :

public class LogMessageBehavior : IEndpointBehavior 
{ 
    public LogMessageBehavior() 
    { } 

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
    { } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) 
    { 
     throw new NotImplementedException(); 
    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) 
    { 
     LogMessageInspector inspector = new LogMessageInspector(); 
     endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector); 
    } 

    public void Validate(ServiceEndpoint endpoint) 
    { 
    } 

} 

public class LogMessageBehaviorExtensionElement : BehaviorExtensionElement 
{ 
    public LogMessageBehaviorExtensionElement() { } 

    public override Type BehaviorType 
    { 
     get 
     { 
      return typeof(LogMessageBehavior); 
     } 
    } 

    protected override object CreateBehavior() 
    { 
     return new LogMessageBehavior(); 
    } 
} 

public class LogMessageInspector : IDispatchMessageInspector 
{ 
    object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext) 
    { 
     throw new NotImplementedException(); 
    } 

    void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) 
    { 
     throw new NotImplementedException(); 
    } 
} 

는 거의 모든 코드는 NotImplementedException과 스텁,하지만 난 모든 메서드 및 속성에 중단 점을 설정합니다. 더 나아가 그들이 어떻게 타격을 받았는지 말할 것입니다.

ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(Environment.bindAddress));    
myserviceHost.Open(); 

Console.WriteLine(myserviceHost.BaseAddresses[0]); 
Console.ReadLine(); 

서비스 클래스는 특별한 어떤 일없이 : 여기

App.config 

<?xml version="1.0"?> 
<configuration> 
    <system.serviceModel> 
    <extensions> 
     <behaviorExtensions> 
     <add name="LogMessage" type="MyService.Extensions.LogMessageBehaviorExtensionElement, MyServiceApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> 
     </behaviorExtensions> 
    </extensions> 
    <behaviors>  
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="True"/> 
      <serviceDebug includeExceptionDetailInFaults="True"/>   
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="LogMessageEndpointBehavior"> 
      <LogMessage /> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 

    <diagnostics> 
     <messageLogging 
      logEntireMessage="true" 
      logMalformedMessages="true" 
      logMessagesAtServiceLevel="true" 
      logMessagesAtTransportLevel="true" 
      maxMessagesToLog="3000" 
      maxSizeOfMessageToLog="20000"/> 
    </diagnostics> 
    <!-- omitted for brewity --> 
    <services> 
     <service name="MyService"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:8733/"/> 
      </baseAddresses> 
     </host> 
     <endpoint address="MyServiceAddress" binding="basicHttpBinding" bindingConfiguration="MyService" contract="MyService" name="MyService" behaviorConfiguration="LogMessageEndpointBehavior"> 
      <identity> 
      <dns value="localhost"/> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 

    <bindings> 
     <basicHttpBinding> 
     <binding name="MyService" closeTimeout="00:01:00" 
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
      maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
      useDefaultWebProxy="true"> 
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
      maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
      <security mode="Transport"> 
      <transport clientCredentialType="None" proxyCredentialType="None" 
       realm="" /> 
      <message clientCredentialType="UserName" algorithmSuite="Default" /> 
      </security> 
     </binding> 
     <!-- omitted for brewity --> 
     </basicHttpBinding> 
    </bindings> 
    </system.serviceModel> 

    <system.diagnostics> 
    <sources> 
     <source name="System.ServiceModel.MessageLogging"> 
     <listeners> 
      <add name="messages" 
      type="System.Diagnostics.XmlWriterTraceListener" 
      initializeData="C:\messages.svclog" /> 
     </listeners> 
     </source> 
    </sources> 
    </system.diagnostics> 

</configuration> 

서비스가 설치하는 방법입니다.

그럼이 구조는 어떻게 작동합니까? 앞에서 언급했듯이 모든 메서드와 속성에 중단 점을 설정합니다. , 서비스가 어떻게 반응하는지 볼 수있는 뭔가를 보내 해보자

1. public LogMessageBehaviorExtensionElement() { } 
2. get { return typeof(LogMessageBehavior); } 
3. get { return typeof(LogMessageBehavior); } (again) 
4. get { return typeof(LogMessageBehavior); } (again) 
5. get { return typeof(LogMessageBehavior); } (again) 

OK : 나는 디버깅을 시작한 후, 우리는이 순서에 중단 점 적중을 얻었다. 그래서 나는 http://localhost:8733/이라는 주소로 WSDL을 사용하여 생성 된 요청을 보내고 유효한 응답을 얻는다. 나는 그것을 위해 SoapUI를 사용했다. VS에서 중단 점 활동이 없습니다! 메시지 관리자가 작동하지 않습니다. 중단 점 서비스 메서드에 충돌, 그 방법은 메시지 검사기없이 실제로 작동하는 보여줍니다.

1. public LogMessageBehavior() { } 
: 우리 중단 점 적중의 순서를 가지고이 옵션에서

ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(Environment.bindAddress));    
myserviceHost.Open(); 

foreach (ServiceEndpoint endpoint in myserviceHost.Description.Endpoints) 
{ 
    endpoint.Behaviors.Add(new LogMessageBehavior()); 
} 

Console.WriteLine(myserviceHost.BaseAddresses[0]); 
Console.ReadLine(); 

:

또한 내가 (따라서의 app.config의 동작을도 명시하지 않고) 설치 서비스에이 코드를 사용하여 동작을 연결 시도

그게 전부입니다. 또한 서비스 요청을 보내는 관리자의 활동도 없습니다.

어떻게 작동시킬 수 있습니까?

+1

[메시지 로깅] (http://msdn.microsoft.com/en-us/library/ms730064.aspx)을 활성화하고 구성해야합니다. –

+0

@ JohnSaunders 나는 그것을 시도했다. 내 app.config를 참조하십시오. 그것은 손상된 로그를 작성하고 심지어 그것으로부터 타임 스탬프가있는 사람이 읽을 수있는 메시지를 얻는 방법을 모르겠습니다. – kseen

+0

"손상"에 대해서는 파일을 강제로 플러시해야합니다. 서비스를 중지하면 그렇게됩니다. IIS에서 호스팅되는 서비스의 경우 웹을 "만지기 만하면됩니다".config - 메모장에서 열고 공백을 입력하고 백 스페이스를 입력 한 다음 Control-S를 입력하십시오. 서비스가 로그를 플러시하고 다시 시작합니다. –

답변

0

동작을 추가 한 후 호스트를 열어보십시오. 그것은 잘 작동합니다.

ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(Environment.bindAddress)); 

foreach (ServiceEndpoint endpoint in myserviceHost.Description.Endpoints) 
{ 
    endpoint.Behaviors.Add(new LogMessageBehavior()); 
} 

myserviceHost.Open(); 

Console.WriteLine(myserviceHost.BaseAddresses[0]); 
Console.ReadLine();