다음을 통해 공유


라우팅 소개

라우팅 서비스는 메시지 콘텐츠를 기반으로 메시지를 라우팅할 수 있는 일반 플러그형 SOAP 중간자를 제공합니다. 라우팅 서비스를 사용하면 서비스 집계, 서비스 버전 관리, 우선 순위 라우팅 및 멀티캐스트 라우팅과 같은 시나리오를 구현할 수 있는 복잡한 라우팅 논리를 만들 수 있습니다. 또한 라우팅 서비스는 기본 대상 엔드포인트로 보낼 때 오류가 발생할 경우 메시지가 전송되는 백업 엔드포인트 목록을 설정할 수 있는 오류 처리를 제공합니다.

이 항목은 라우팅 서비스를 새로 만들기 위한 것이며 라우팅 서비스의 기본 구성 및 호스팅에 대해 설명합니다.

구성 / 설정

라우팅 서비스는 클라이언트 애플리케이션에서 메시지를 수신하고 메시지를 하나 이상의 대상 엔드포인트로 라우팅하는 하나 이상의 서비스 엔드포인트를 노출하는 WCF 서비스로 구현됩니다. 서비스는 서비스에서 노출하는 서비스 엔드포인트에 적용되는 RoutingBehavior을 제공합니다. 이 동작은 서비스가 작동하는 방식의 다양한 측면을 구성하는 데 사용됩니다. 구성 파일을 사용하는 경우 구성 편의성을 위해 RoutingBehavior에 매개 변수가 지정됩니다. 코드 기반 시나리오에서는 이러한 매개 변수를 개체의 RoutingConfiguration 일부로 지정한 다음 RoutingBehavior에 전달할 수 있습니다.

시작할 때 이 동작은 SoapProcessingBehavior를 추가하여 메시지의 SOAP 처리를 수행할 수 있도록 클라이언트 엔드포인트에 적용합니다. 이렇게 하면 라우팅 서비스에서 메시지를 받은 엔드포인트와 다른 MessageVersion 이 필요한 엔드포인트로 메시지를 전송할 수 있습니다. 또한 RoutingBehavior는 런타임에 라우팅 서비스 구성을 수정하기 위한 접근성 지점을 제공하는 서비스 확장을 RoutingExtension등록합니다.

RoutingConfiguration 클래스는 라우팅 서비스의 구성을 구성하고 업데이트하는 일관된 방법을 제공합니다. 라우팅 서비스에 대한 설정으로 작동하고 서비스가 시작될 때 RoutingBehavior를 구성하는 데 사용되거나 런타임에 라우팅 구성을 수정하기 위해 RoutingExtension 에 전달되는 매개 변수를 포함합니다.

메시지의 콘텐츠 기반 라우팅을 수행하는 데 사용되는 라우팅 논리는 여러 MessageFilter 개체를 필터 테이블(MessageFilterTable<TFilterData> 개체)로 그룹화하여 정의됩니다. 들어오는 메시지는 필터 테이블에 포함된 메시지 필터 및 대상 엔드포인트로 전달되는 메시지와 일치하는 각 MessageFilter 에 대해 평가됩니다. 메시지를 라우팅하는 데 사용해야 하는 필터 테이블은 RoutingBehavior 를 구성에서 사용하거나 RoutingConfiguration 개체를 사용하여 코드를 통해 지정됩니다.

엔드포인트 정의

사용할 라우팅 논리를 정의하여 구성을 시작해야 하는 것처럼 보일 수 있지만, 첫 번째 단계는 메시지를 라우팅할 엔드포인트의 모양을 결정하는 것입니다. 라우팅 서비스는 메시지를 받고 보내는 데 사용되는 채널의 모양을 정의하는 계약을 사용하므로 입력 채널의 모양이 출력 채널의 모양과 일치해야 합니다. 예를 들어 요청-회신 채널 셰이프를 사용하는 엔드포인트로 라우팅하는 경우 인바운드 엔드포인트에서 호환되는 계약(예: IRequestReplyRouter)을 사용해야 합니다.

즉, 대상 엔드포인트가 여러 통신 패턴(예: 단방향 및 양방향 작업 혼합)이 있는 계약을 사용하는 경우 메시지를 모두 수신하고 라우팅할 수 있는 단일 서비스 엔드포인트를 만들 수 없습니다. 호환되는 셰이프가 있는 엔드포인트를 확인하고 대상 엔드포인트로 라우팅할 메시지를 받는 데 사용할 하나 이상의 서비스 엔드포인트를 정의해야 합니다.

비고

여러 통신 패턴을 지정하는 계약(예: 단방향 및 양방향 작업 혼합)을 사용하는 경우 해결 방법은 라우팅 서비스에서 IDuplexSessionRouter이중 계약을 사용하는 것입니다. 그러나 이는 바인딩이 이중 통신이 가능해야 하며, 이는 모든 시나리오에서 가능하지 않을 수 있음을 의미합니다. 이것이 불가능한 시나리오에서는 통신을 여러 엔드포인트로 팩터링하거나 애플리케이션을 수정해야 할 수 있습니다.

라우팅 계약에 대한 자세한 내용은 라우팅 계약을 참조하세요.

서비스 엔드포인트가 정의되면 RoutingBehavior를 사용하여 특정 RoutingConfiguration을 엔드포인트와 연결할 수 있습니다. 구성 파일을 사용하여 라우팅 서비스를 구성할 때 RoutingBehavior 는 이 엔드포인트에서 받은 메시지를 처리하는 데 사용되는 라우팅 논리가 포함된 필터 테이블을 지정하는 데 사용됩니다. 프로그래밍 방식으로 라우팅 서비스를 구성하는 경우 RoutingConfiguration을 사용하여 필터 테이블을 지정할 수 있습니다.

다음 예제에서는 프로그래밍 방식으로 및 구성 파일을 사용하여 라우팅 서비스에서 사용하는 서비스 및 클라이언트 엔드포인트를 정의합니다.

<services>
  <!--ROUTING SERVICE -->
  <service behaviorConfiguration="routingData"
            name="System.ServiceModel.Routing.RoutingService">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8000/routingservice/router"/>
      </baseAddresses>
    </host>
    <!-- Define the service endpoints that are receive messages -->
    <endpoint address=""
              binding="wsHttpBinding"
              name="reqReplyEndpoint"
              contract="System.ServiceModel.Routing.IRequestReplyRouter" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="routingData">
      <serviceMetadata httpGetEnabled="True"/>
      <!-- Add the RoutingBehavior and specify the Routing Table to use -->
      <routing filterTableName="routingTable1" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<client>
<!-- Define the client endpoint(s) to route messages to -->
  <endpoint name="CalculatorService"
            address="http://localhost:8000/servicemodelsamples/service"
            binding="wsHttpBinding" contract="*" />
</client>
//set up some communication defaults
string clientAddress = "http://localhost:8000/servicemodelsamples/service";
string routerAddress = "http://localhost:8000/routingservice/router";
Binding routerBinding = new WSHttpBinding();
Binding clientBinding = new WSHttpBinding();
//add the endpoint the router uses to receive messages
serviceHost.AddServiceEndpoint(
     typeof(IRequestReplyRouter),
     routerBinding,
     routerAddress);
//create the client endpoint the router routes messages to
ContractDescription contract = ContractDescription.GetContract(
     typeof(IRequestReplyRouter));
ServiceEndpoint client = new ServiceEndpoint(
     contract,
     clientBinding,
     new EndpointAddress(clientAddress));
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
….
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
//attach the behavior to the service host
serviceHost.Description.Behaviors.Add(
     new RoutingBehavior(rc));

이 예제에서는 라우팅할 메시지를 수신하는 데 사용되는 주소 http://localhost:8000/routingservice/router가 있는 단일 엔드포인트를 노출하도록 라우팅 서비스를 구성합니다. 메시지는 요청-회신 엔드포인트로 라우팅되므로 서비스 엔드포인트는 계약을 사용합니다 IRequestReplyRouter . 또한 이 구성은 라우팅되는 메시지의 http://localhost:8000/servicemodelsample/service 단일 클라이언트 엔드포인트를 정의합니다. "routingTable1"이라는 필터 테이블(표시되지 않음)에는 메시지를 라우팅하는 데 사용되는 라우팅 논리가 포함되어 있으며 RoutingBehavior (구성 파일의 경우) 또는 RoutingConfiguration (프로그래밍 방식 구성)을 사용하여 서비스 엔드포인트와 연결됩니다.

라우팅 논리

메시지를 라우팅하는 데 사용되는 라우팅 논리를 정의하려면 들어오는 메시지에 포함된 데이터를 고유하게 수행할 수 있는지 결정해야 합니다. 예를 들어 동일한 SOAP 작업을 공유하기 위해 라우팅하는 모든 대상 엔드포인트의 경우 메시지 내에 포함된 작업의 값은 메시지를 라우팅해야 하는 특정 엔드포인트를 나타내는 좋은 지표가 아닙니다. 메시지를 특정 엔드포인트로 고유하게 라우팅해야 하는 경우 메시지가 라우팅되는 대상 엔드포인트를 고유하게 식별하는 데이터를 필터링해야 합니다.

라우팅 서비스는 주소, 작업, 엔드포인트 이름 또는 XPath 쿼리와 같은 메시지 내의 특정 값을 검사하는 여러 MessageFilter 구현을 제공합니다. 이러한 구현 중 요구 사항을 충족하지 않는 경우 사용자 지정 MessageFilter 구현을 만들 수 있습니다. 메시지 필터 및 라우팅 서비스에서 사용하는 구현 비교에 대한 자세한 내용은 메시지 필터 및필터 선택을 참조하세요.

여러 메시지 필터는 각 MessageFilter 를 대상 엔드포인트와 연결하는 필터 테이블로 함께 구성됩니다. 필요에 따라 필터 테이블을 사용하여 라우팅 서비스에서 전송 실패 시 메시지를 보내려고 시도하는 백업 엔드포인트 목록을 지정할 수도 있습니다.

기본적으로 필터 테이블 내의 모든 메시지 필터는 동시에 평가됩니다. 그러나 메시지 필터가 Priority 특정 순서로 평가되도록 지정하면 됩니다. 우선 순위가 가장 높은 모든 항목이 먼저 평가되며, 우선 순위가 더 높은 일치 항목이 발견되면 우선 순위가 낮은 메시지 필터는 평가되지 않습니다. 필터 테이블에 대한 자세한 내용은 메시지 필터를 참조하세요.

다음 예제들은 MatchAllMessageFilter을 사용하며, 이는 모든 메시지에 대해 true로 평가됩니다. 이 MessageFilterMessageFilter 를 "CalculatorService"라는 클라이언트 엔드포인트와 연결하는 "routingTable1" 필터 테이블에 추가됩니다. 그런 다음 RoutingBehavior 는 이 테이블을 사용하여 서비스 엔드포인트에서 처리된 메시지를 라우팅하도록 지정합니다.

<behaviors>
  <serviceBehaviors>
    <behavior name="routingData">
      <serviceMetadata httpGetEnabled="True"/>
      <!-- Add the RoutingBehavior and specify the Routing Table to use -->
      <routing filterTableName="routingTable1" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<!--ROUTING SECTION -->
<routing>
  <filters>
    <filter name="MatchAllFilter1" filterType="MatchAll" />
  </filters>
  <filterTables>
    <table name="routingTable1">
      <filters>
        <add filterName="MatchAllFilter1" endpointName="CalculatorService" />
      </filters>
    </table>
  </filterTables>
</routing>
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
//create the endpoint list that contains the endpoints to route to
//in this case we have only one
List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
endpointList.Add(client);
//add a MatchAll filter to the Router's filter table
//map it to the endpoint list defined earlier
//when a message matches this filter, it is sent to the endpoint contained in the list
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);

비고

기본적으로 라우팅 서비스는 메시지의 헤더만 평가합니다. 필터가 메시지 본문에 액세스할 수 있도록 하려면 RouteOnHeadersOnlyfalse으로 설정해야 합니다.

멀티캐스트

많은 라우팅 서비스 구성은 메시지를 하나의 특정 엔드포인트로만 라우팅하는 배타적 필터 논리를 사용하지만 지정된 메시지를 여러 대상 엔드포인트로 라우팅해야 할 수 있습니다. 메시지를 여러 대상으로 멀티캐스트하려면 다음 조건이 충족되어야 합니다.

  • 요청에 대한 응답으로 클라이언트 애플리케이션에서 하나의 회신만 수신할 수 있으므로 채널 셰이프는 요청-회신(단방향 또는 이중일 수 있음)해서는 안 됩니다.

  • 메시지를 평가할 때 여러 필터가 true를 반환해야 합니다.

이러한 조건이 충족되면 메시지는 true로 평가되는 모든 필터의 모든 엔드포인트로 라우팅됩니다. 다음 예제에서는 메시지 내 엔드포인트 주소가 http://localhost:8000/routingservice/router/rounding일 경우, 메시지가 두 엔드포인트로 모두 라우팅되는 라우팅 구성을 정의합니다.

<!--ROUTING SECTION -->
<routing>
  <filters>
    <filter name="MatchAllFilter1" filterType="MatchAll" />
    <filter name="RoundingFilter1" filterType="EndpointAddress"
            filterData="http://localhost:8000/routingservice/router/rounding" />
  </filters>
  <filterTables>
    <table name="routingTable1">
      <filters>
        <add filterName="MatchAllFilter1" endpointName="CalculatorService" />
        <add filterName="RoundingFilter1" endpointName="RoundingCalcService" />
      </filters>
    </table>
  </filterTables>
</routing>
rc.FilterTable.Add(new MatchAllMessageFilter(), calculatorEndpointList);
rc.FilterTable.Add(new EndpointAddressMessageFilter(new EndpointAddress(
    "http://localhost:8000/routingservice/router/rounding")),
    roundingCalcEndpointList);

SOAP 처리

서로 다른 프로토콜 간의 메시지 라우팅을 지원하기 위해 RoutingBehavior 는 기본적으로 메시지가 라우팅되는 모든 클라이언트 엔드포인트에 추가 SoapProcessingBehavior 합니다. 이 동작은 메시지를 엔드포인트로 라우팅하기 전에 자동으로 새 MessageVersion 을 만들고, 요청 클라이언트 애플리케이션으로 반환하기 전에 응답 문서에 대해 호환되는 MessageVersion 을 만듭니다.

아웃바운드 메시지에 대한 새 MessageVersion 을 만드는 단계는 다음과 같습니다.

요청 처리

  • 아웃바운드 바인딩/채널의 MessageVersion 을 가져옵니다.

  • 원본 메시지의 본문 판독기를 가져옵니다.

  • 동일한 작업, 본문 판독기 및 새 MessageVersion을 사용하여 새 메시지를 만듭니다.

  • != Addressing인 경우 To, From, FaultTo 및 RelatesTo 헤더를 새 메시지에 복사합니다.

  • 모든 메시지 속성을 새 메시지에 복사합니다.

  • 응답을 처리할 때 사용할 원래 요청 메시지를 저장합니다.

  • 새 요청 메시지를 반환합니다.

응답 처리

  • 원래 요청 메시지의 MessageVersion 을 가져옵니다.

  • 수신된 응답 메시지에 대한 본문 판독기를 가져옵니다.

  • 원래 요청 메시지의 동일한 작업, 본문 판독기 및 MessageVersion 을 사용하여 새 응답 메시지를 만듭니다.

  • != Addressing인 경우 To, From, FaultTo 및 RelatesTo 헤더를 새 메시지에 복사합니다.

  • 새 메시지에 메시지 속성을 복사합니다.

  • 새 응답 메시지를 반환합니다.

기본적으로 SoapProcessingBehavior 는 서비스가 시작될 때 클라이언트 엔드포인트에 RoutingBehavior 자동으로 추가되지만 SOAP 처리가 속성을 사용하여 SoapProcessingEnabled 모든 클라이언트 엔드포인트에 추가되는지 여부를 제어할 수 있습니다. 또한 특정 엔드포인트에 직접 동작을 추가하고 SOAP 처리를 보다 세부적으로 제어해야 하는 경우 엔드포인트 수준에서 이 동작을 사용하거나 사용하지 않도록 설정할 수 있습니다.

비고

원래 요청 메시지와 다른 MessageVersion이 필요한 엔드포인트에 대해 SOAP 처리를 사용하지 않도록 설정한 경우 대상 엔드포인트로 메시지를 보내기 전에 필요한 SOAP 수정을 수행하기 위한 사용자 지정 메커니즘을 제공해야 합니다.

다음 예제에서는 soapProcessingEnabled 속성을 사용하여 SoapProcessingBehavior 가 모든 클라이언트 엔드포인트에 자동으로 추가되지 않도록 방지합니다.

<behaviors>
  <!--default routing service behavior definition-->
  <serviceBehaviors>
    <behavior name="routingConfiguration">
      <routing filterTableName="filterTable1" soapProcessingEnabled="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
//create the default RoutingConfiguration
RoutingConfiguration rc = new RoutingConfiguration();
rc.SoapProcessingEnabled = false;

동적 구성

클라이언트 엔드포인트를 추가하거나 메시지를 라우팅하는 데 사용되는 필터를 수정해야 하는 경우 런타임에 구성을 동적으로 업데이트하여 라우팅 서비스를 통해 현재 메시지를 수신하는 엔드포인트에 대한 서비스가 중단되지 않도록 해야 합니다. 구성 파일 또는 호스트 애플리케이션의 코드를 수정하는 것으로는 항상 충분하지 않습니다. 두 방법 중 하나를 사용하려면 애플리케이션을 재활용해야 하므로 현재 전송 중인 모든 메시지가 손실될 수 있으며 서비스가 다시 시작될 때까지 기다리는 동안 가동 중지 시간이 발생할 수 있습니다.

RoutingConfiguration은 프로그래밍 방식으로만 수정할 수 있습니다. 처음에는 구성 파일을 사용하여 서비스를 구성할 수 있지만, 새 RoutingConfiguration을 생성하고 서비스 확장 프로그램에서 노출하는 메서드에 매개 변수로 전달하여 런타임에만 구성을 ApplyConfiguration 수정할 RoutingExtension 수 있습니다. 현재 전송 중인 모든 메시지는 이전 구성을 사용하여 계속 라우팅되지만 ApplyConfiguration 호출 후에 받은 메시지는 새 구성을 사용합니다. 다음 예제에서는 라우팅 서비스의 인스턴스를 만든 다음 구성을 수정하는 방법을 보여 줍니다.

RoutingConfiguration routingConfig = new RoutingConfiguration();
routingConfig.RouteOnHeadersOnly = true;
routingConfig.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
RoutingBehavior routing = new RoutingBehavior(routingConfig);
routerHost.Description.Behaviors.Add(routing);
routerHost.Open();
// Construct a new RoutingConfiguration
RoutingConfiguration rc2 = new RoutingConfiguration();
ServiceEndpoint clientEndpoint = new ServiceEndpoint();
ServiceEndpoint clientEndpoint2 = new ServiceEndpoint();
// Add filters to the FilterTable in the new configuration
rc2.FilterTable.add(new MatchAllMessageFilter(),
       new List<ServiceEndpoint>() { clientEndpoint });
rc2.FilterTable.add(new MatchAllMessageFilter(),
       new List<ServiceEndpoint>() { clientEndpoint2 });
rc2.RouteOnHeadersOnly = false;
// Apply the new configuration to the Routing Service hosted in
routerHost.routerHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc2);

비고

이러한 방식으로 라우팅 서비스를 업데이트하는 경우 새 구성만 전달할 수 있습니다. 현재 구성의 선택 요소만 수정하거나 현재 구성에 새 항목을 추가할 수는 없습니다. 기존 구성을 대체하는 새 구성을 만들고 전달해야 합니다.

비고

이전 구성을 사용하여 연 모든 세션은 이전 구성을 계속 사용합니다. 새 구성은 새 세션에서만 사용됩니다.

오류 처리

메시지를 보내는 시도 중에 CommunicationException가 발생하면 오류 처리가 수행됩니다. 이러한 예외는 일반적으로 정의된 클라이언트 엔드포인트(예: , 또는EndpointNotFoundException)와 통신하는 동안 문제가 발생했음을 ServerTooBusyExceptionCommunicationObjectFaultedException나타냅니다. 오류 처리 코드는 TimeoutException가 발생할 때 이를 캐치하고 다시 전송을 시도합니다. 이는 CommunicationException에서 파생되지 않은 또 다른 일반적인 예외입니다.

위의 예외 중 하나가 발생하면 라우팅 서비스는 백업 엔드포인트 목록으로 전환됩니다. 통신 오류로 모든 백업 엔드포인트가 실패하거나 엔드포인트가 대상 서비스 내에서 오류를 나타내는 예외를 반환하는 경우 라우팅 서비스는 클라이언트 애플리케이션에 오류를 반환합니다.

비고

오류 처리 기능은 메시지를 보내려고 할 때와 채널을 닫을 때 발생하는 예외를 캡처하고 처리합니다. 오류 처리 코드는 통신하는 애플리케이션 엔드포인트에서 만든 예외를 검색하거나 처리하기 위한 것이 아닙니다. 서비스에서 throw된 FaultException A는 라우팅 서비스에 FaultMessage 로 나타나고 클라이언트로 다시 전달됩니다.

라우팅 서비스가 메시지를 릴레이하려고 할 때 오류가 발생하면, 라우팅 서비스가 없는 경우에 보통 받는 FaultException 대신 클라이언트 측에서 EndpointNotFoundException을/를 받을 수 있습니다. 따라서 라우팅 서비스는 중첩된 예외를 검사하지 않는 한 예외를 마스크하고 완전한 투명도를 제공하지 않을 수 있습니다.

예외 추적

목록의 엔드포인트에 메시지를 보내는 데 실패하면 라우팅 서비스는 결과 예외 데이터를 추적하고 예외 세부 정보를 Exceptions라는 메시지 속성으로 첨부합니다. 이렇게 하면 예외 데이터가 유지되고 메시지 검사기를 통해 사용자 프로그래밍 방식으로 액세스할 수 있습니다. 예외 데이터는 메시지를 보내려고 할 때 발생하는 예외 세부 정보를 엔드포인트 이름과 연결하는 사전에 메시지별로 저장됩니다.

백업 엔드포인트

필터 테이블 내의 각 필터 항목은 필요에 따라 기본 엔드포인트로 보낼 때 전송 실패 시 사용되는 백업 엔드포인트 목록을 지정할 수 있습니다. 이러한 오류가 발생하면 라우팅 서비스는 백업 엔드포인트 목록의 첫 번째 항목으로 메시지를 전송하려고 시도합니다. 이 보내기 시도에서도 전송 오류가 발생하면 백업 목록의 다음 엔드포인트가 시도됩니다. 라우팅 서비스는 메시지가 성공적으로 수신되거나, 모든 엔드포인트가 전송 오류를 반환하거나, 비 전송 실패가 엔드포인트에서 반환될 때까지 목록의 각 엔드포인트로 메시지를 계속 보냅니다.

다음 예제에서는 백업 목록을 사용하도록 라우팅 서비스를 구성합니다.

<routing>
  <filters>
    <!-- Create a MatchAll filter that catches all messages -->
    <filter name="MatchAllFilter1" filterType="MatchAll" />
  </filters>
  <filterTables>
    <!-- Set up the Routing Service's Message Filter Table -->
    <filterTable name="filterTable1">
        <!-- Add an entry that maps the MatchAllMessageFilter to the dead destination -->
        <!-- If that endpoint is down, tell the Routing Service to try the endpoints -->
        <!-- Listed in the backupEndpointList -->
        <add filterName="MatchAllFilter1" endpointName="deadDestination" backupList="backupEndpointList"/>
    </filterTable>
  </filterTables>
  <!-- Create the backup endpoint list -->
  <backupLists>
    <!-- Add an endpoint list that contains the backup destinations -->
    <backupList name="backupEndpointList">
      <add endpointName="realDestination" />
      <add endpointName="backupDestination" />
    </backupList>
  </backupLists>
</routing>
//create the endpoint list that contains the service endpoints we want to route to
List<ServiceEndpoint> backupList = new List<ServiceEndpoint>();
//add the endpoints in the order that the Routing Service should contact them
//first add the endpoint that we know is down
//clearly, normally you wouldn't know that this endpoint was down by default
backupList.Add(fakeDestination);
//then add the real Destination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationException when sending
//to the previous endpoint in the list.
backupList.Add(realDestination);
//add the backupDestination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationsException when sending
//to the previous endpoints in the list
backupList.Add(backupDestination);
//create the default RoutingConfiguration option
RoutingConfiguration rc = new RoutingConfiguration();
//add a MatchAll filter to the Routing Configuration's filter table
//map it to the list of endpoints defined above
//when a message matches this filter, it is sent to the endpoints in the list in order
//if an endpoint is down or does not respond (which the first endpoint won't
//since the client does not exist), the Routing Service automatically moves the message
//to the next endpoint in the list and try again.
rc.FilterTable.Add(new MatchAllMessageFilter(), backupList);

지원되는 오류 패턴

다음 표에서는 백업 엔드포인트 목록의 사용과 호환되는 패턴과 특정 패턴에 대한 오류 처리 세부 정보를 설명하는 노트를 설명합니다.

패턴 세션 트랜잭션 문맥을 수신하다 지원되는 백업 목록 비고
One-Way 백업 엔드포인트에서 메시지를 다시 보내려고 시도합니다. 이 메시지가 멀티캐스트되는 경우 실패한 채널의 메시지만 백업 대상으로 이동됩니다.
One-Way ✔️ 아니오 예외가 발생하고 트랜잭션이 돌려집니다.
One-Way ✔️ 백업 엔드포인트에서 메시지를 다시 보내려고 시도합니다. 메시지가 성공적으로 수신되면 모든 수신 컨텍스트를 완료합니다. 메시지가 엔드포인트에서 성공적으로 수신되지 않은 경우 수신 컨텍스트를 완료하지 마세요.

이 메시지가 멀티캐스트되는 경우 메시지가 하나 이상의 엔드포인트(기본 또는 백업)에서 성공적으로 수신된 경우에만 수신 컨텍스트가 완료됩니다. 멀티캐스트 경로의 엔드포인트 중 어느 것도 메시지를 성공적으로 수신하지 않는 경우 수신 컨텍스트를 완료하지 마세요.
One-Way ✔️ ✔️ 이전 트랜잭션을 중단하고, 새 트랜잭션을 만들고, 모든 메시지를 다시 보냅니다. 오류가 발생한 메시지는 백업 대상으로 전송됩니다.

모든 전송이 성공하는 트랜잭션이 만들어지면 수신 컨텍스트를 완료하고 트랜잭션을 커밋합니다.
One-Way ✔️ 백업 엔드포인트에서 메시지를 다시 보내려고 시도합니다. 멀티캐스트 시나리오에서는 오류가 발생한 세션 또는 세션이 닫히지 못한 세션의 메시지만 백업 대상에 다시 전송됩니다.
One-Way ✔️ ✔️ 아니오 예외가 발생하고 트랜잭션이 돌려집니다.
One-Way ✔️ ✔️ 백업 엔드포인트에서 메시지를 다시 보내려고 시도합니다. 모든 메시지가 오류 없이 완료되면 세션은 더 이상 메시지를 나타내지 않으며 라우팅 서비스는 모든 아웃바운드 세션 채널을 성공적으로 닫고, 모든 수신 컨텍스트가 완료되고, 인바운드 세션 채널이 닫힙니다.
One-Way ✔️ ✔️ ✔️ 현재 트랜잭션을 중단하고 새 트랜잭션을 만듭니다. 세션의 모든 이전 메시지를 다시 보냅니다. 모든 메시지가 성공적으로 전송되고 세션이 더 이상 메시지를 나타내지 않는 트랜잭션이 만들어지면 모든 아웃바운드 세션 채널이 닫히고, 수신 컨텍스트가 모두 트랜잭션으로 완료되고, 인바운드 세션 채널이 닫히고, 트랜잭션이 커밋됩니다.

세션이 멀티캐스트되는 경우 오류가 없는 메시지는 이전과 동일한 대상으로 다시 전송되고 오류가 발생한 메시지는 백업 대상으로 전송됩니다.
Two-Way 백업 대상으로 보냅니다. 채널이 응답 메시지를 반환한 후 원래 클라이언트에 응답을 반환합니다.
Two-Way ✔️ 채널의 모든 메시지를 백업 대상으로 보냅니다. 채널이 응답 메시지를 반환한 후 원래 클라이언트에 응답을 반환합니다.
Two-Way ✔️ 아니오 예외가 발생하고 트랜잭션이 돌려집니다.
Two-Way ✔️ ✔️ 아니오 예외가 발생하고 트랜잭션이 돌려집니다.
이중 아니오 비 세션 이중 통신은 현재 지원되지 않습니다.
이중 ✔️ 백업 대상으로 보냅니다.

호스팅

라우팅 서비스는 WCF 서비스로 구현되므로 애플리케이션 내에서 자체 호스팅되거나 IIS 또는 WAS에서 호스트되어야 합니다. 이러한 호스팅 환경에서 사용할 수 있는 자동 시작 및 수명 주기 관리 기능을 활용하려면 라우팅 서비스를 IIS, WAS 또는 Windows 서비스 애플리케이션에서 호스트하는 것이 좋습니다.

다음 예제에서는 애플리케이션에서 라우팅 서비스를 호스팅하는 방법을 보여 줍니다.

using (ServiceHost serviceHost =
                new ServiceHost(typeof(RoutingService)))

IIS 또는 WAS 내에서 라우팅 서비스를 호스트하려면 서비스 파일(.svc)을 만들거나 서비스의 구성 기반 활성화를 사용해야 합니다. 서비스 파일을 사용하는 경우 서비스 매개 변수를 RoutingService 사용하여 지정해야 합니다. 다음 예제에는 IIS 또는 WAS를 사용하여 라우팅 서비스를 호스트하는 데 사용할 수 있는 샘플 서비스 파일이 포함되어 있습니다.

<%@ ServiceHost Language="C#" Debug="true" Service="System.ServiceModel.Routing.RoutingService,
     System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,
     PublicKeyToken=31bf3856ad364e35" %>

라우팅 서비스 및 가장

WCF 라우팅 서비스는 메시지를 보내고 받을 때 대리 실행과 함께 사용할 수 있습니다. 모든 일반적인 Windows 권한 위임 제약 조건이 적용됩니다. 자체 서비스를 작성할 때 가장을 사용하도록 서비스 또는 계정 권한을 설정해야 하는 경우 라우팅 서비스에서 가장을 사용하려면 동일한 단계를 수행해야 합니다. 자세한 내용은 위임 및 가장을 참조하세요.

라우팅 서비스에서 가장하려면 ASP.NET 호환 모드에서 ASP.NET 가장을 사용하거나, 가장을 허용하도록 구성된 Windows 자격 증명을 사용해야 합니다. ASP.NET 호환성 모드에 대한 자세한 내용은 WCF 서비스 및 ASP.NET 참조하세요.

경고

WCF 라우팅 서비스는 기본 인증을 통한 임퍼서네이션을 지원하지 않습니다.

라우팅 서비스에서 ASP.NET 가장을 사용하려면 서비스 호스팅 환경에서 ASP.NET 호환성 모드를 사용하도록 설정합니다. 라우팅 서비스는 이미 ASP.NET 호환 모드를 활성화하는 것으로 표시되었으며 사용자 가장하기가 자동으로 사용되도록 설정됩니다. 가장은 라우팅 서비스와의 ASP.NET 통합에서 유일하게 지원되는 사용입니다.

라우팅 서비스에서 Windows 자격 증명 가장을 사용하려면 자격 증명과 서비스를 모두 구성해야 합니다. 클라이언트 자격 증명 개체(WindowsClientCredential, ChannelFactory에서 액세스 가능)는 대리 실행을 허용하도록 설정해야 하는 AllowedImpersonationLevel 속성을 정의합니다. 마지막으로 서비스에서 ServiceAuthorizationBehavior 동작을 구성하여 ImpersonateCallerForAllOperationstrue로 설정해야 합니다. 라우팅 서비스는 이 플래그를 사용하여 가장을 사용하도록 설정된 메시지를 전달하기 위한 클라이언트를 만들지 여부를 결정합니다.

참고하십시오