다음을 통해 공유


Custom Message Filter

이 샘플에서는 WCF(Windows Communication Foundation)에서 메시지를 끝점에 디스패치할 때 사용하는 메시지 필터를 대체하는 방법을 보여 줍니다.

Aa717046.note(ko-kr,VS.100).gif참고:
이 샘플의 설치 절차 및 빌드 지침은 이 항목의 끝부분에 나와 있습니다.

채널의 첫 번째 메시지가 서버에 도착하면 서버에서는 해당 URI에 연결된 끝점 중에서 해당 메시지를 받을 끝점(있는 경우)를 결정해야 합니다. 이 프로세스는 EndpointDispatcher에 연결된 MessageFilter 개체에 의해 제어됩니다.

서비스의 각 끝점에는 단일 EndpointDispatcher가 있습니다. EndpointDispatcher에는 AddressFilterContractFilter가 모두 있습니다. 이러한 두 필터를 결합하면 해당 끝점에 사용된 메시지 필터가 됩니다.

기본적으로 끝점에 대한 AddressFilter는 서비스 끝점의 EndpointAddress와 일치하는 주소로 해당 주소가 지정된 모든 메시지와 일치합니다. 기본적으로 끝점에 대한 ContractFilter에서는 들어오는 메시지의 동작을 검사하고 서비스 끝점 계약 작업 동작 중 하나에 해당하는 동작과 메시지를 일치시킵니다. 이때 IsInitiating=true 동작만 고려됩니다. 따라서 기본적으로 끝점에 대한 필터는 두 메시지의 받는 사람 헤더가 끝점의 EndpointAddress인 경우에만 일치하고 메시지의 동작은 끝점 작업의 동작 중 하나와 일치합니다.

이러한 필터는 동작을 사용하여 변경할 수 있습니다. 이 샘플에서 서비스는 EndpointDispatcherAddressFilterContractFilter를 대체하는 IEndpointBehavior를 만듭니다.

class FilteringEndpointBehavior : IEndpointBehavior …

다음과 같이 두 개의 주소 필터가 정의됩니다.

// Matches any message whose To address contains the letter 'e'
class MatchEAddressFilter : MessageFilter …
// Matches any message whose To address does not contain the letter 'e'
class MatchNoEAddressFilter : MessageFilter

FilteringEndpointBehavior는 구성 가능하며 두 가지 다른 변형에 대해 허용됩니다.

public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement

변형 1에서는 'e'를 포함하지만 동작이 있는 주소만 일치하고 변형 2에서는 'e'가 없는 주소만 일치합니다.

if (Variation == 1)
    return new FilteringEndpointBehavior(
        new MatchEAddressFilter(), new MatchAllMessageFilter());
else
    return new FilteringEndpointBehavior(
        new MatchNoEAddressFilter(), new MatchAllMessageFilter());

구성 파일에서 서비스는 새 동작을 등록합니다.

<extensions>
    <behaviorExtensions>
        <add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
    </behaviorExtensions>
</extensions>    

그런 다음 서비스에서는 각 변형에 대한 endpointBehavior 구성을 만듭니다.

<endpointBehaviors>
    <behavior name="endpoint1">
        <filteringEndpointBehavior variation="1" />
    </behavior>
    <behavior name="endpoint2">
        <filteringEndpointBehavior variation="2" />
    </behavior>
</endpointBehaviors>

마지막으로 서비스의 끝점은 behaviorConfigurations 중 하나를 참조합니다.

<endpoint address=""
        bindingConfiguration="ws"
        listenUri="" 
        binding="wsHttpBinding"
        contract="Microsoft.ServiceModel.Samples.IHello" 
        behaviorConfiguration="endpoint2" />

클라이언트 응용 프로그램의 구현은 간단합니다. 이 구현에서는 서비스의 URI에 대한 채널 두 개를 만들고 해당 값을 두 번째 via 매개 변수로 CreateChannel에 전달함으로써 각 채널에서 단일 메시지를 보냅니다. 그러나 각각 다른 끝점 주소를 사용합니다. 따라서 클라이언트의 아웃바운드 메시지에는 다른 받는 사람이 지정되고 클라이언트의 출력에 표시된 대로 서버는 그에 따라 응답합니다.

Sending message to urn:e...
Exception: The message with To 'urn:e' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher.  Check that the sender and receiver's EndpointAddresses agree.

Sending message to urn:a...
Hello

서버의 구성 파일에서 변형을 전환하면 필터가 대체되고 클라이언트에 반대 동작이 표시됩니다. 즉, urn:e에 대한 메시지는 성공하고 urn:a에 대한 메시지는 실패합니다.

<endpoint address=""
          bindingConfiguration="ws"
          listenUri="" 
          binding="wsHttpBinding"
          contract="Microsoft.ServiceModel.Samples.IHello" 
          behaviorConfiguration="endpoint1" />
Aa717046.Important(ko-kr,VS.100).gif 참고:
컴퓨터에 이 샘플이 이미 설치되어 있을 수도 있습니다. 계속하기 전에 다음(기본) 디렉터리를 확인하십시오.

<InstallDrive>:\WF_WCF_Samples

이 디렉터리가 없으면 Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4로 이동하여 WCF(Windows Communication Foundation) 및 WF 샘플을 모두 다운로드하십시오. 이 샘플은 다음 디렉터리에 있습니다.

<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\MessageFilter

샘플을 설치, 빌드 및 실행하려면

  1. 솔루션을 빌드하려면 Windows Communication Foundation 샘플 빌드의 지침을 따릅니다.

  2. 단일 컴퓨터 구성에서 샘플을 실행하려면 Running the Windows Communication Foundation Samples의 지침을 따릅니다.

  3. 다중 컴퓨터 구성에서 샘플을 실행하려면 Running the Windows Communication Foundation Samples의 지침을 따르고 Client.cs에서 다음 줄을 변경합니다.

    Uri serviceVia = new Uri("https://localhost/ServiceModelSamples/service.svc");
    

    localhost를 서버 이름으로 바꿉니다.

    Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");