다음을 통해 공유


사용자 지정 메시지 필터

MessageFilter 샘플은 WCF(Windows Communication Foundation)가 메시지를 엔드포인트로 발송하는 데 사용하는 메시지 필터를 바꾸는 방법을 보여 줍니다.

참고 항목

이 샘플의 설치 절차 및 빌드 지침은 이 항목의 끝부분에 나와 있습니다.

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

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

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

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

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(EndpointAddress)에 전달함으로써 각 채널에서 단일 메시지를 보냅니다. 그러나 각각 다른 엔드포인트 주소를 사용합니다. 따라서 클라이언트의 아웃바운드 메시지에는 다른 받는 사람이 지정되고 클라이언트의 출력에 표시된 대로 서버는 그에 따라 응답합니다.

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

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

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

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

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

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

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

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