Создание маршрутизатора WCF - Семантика адресации по умолчанию

ОГЛАВЛЕНИЕ

Семантика адресации по умолчанию

В выпуске рубрики «Станция техобслуживания» за июнь 2007 года (msdn.microsoft.com/msdnmag/issues/07/06/ServiceStation) Аарон Сконнард (Aaron Skonnard) объяснил, как WCF обрабатывает логическую и физическую адресацию конечных точек, адресацию заголовков и фильтрацию сообщений. В этом разделе я рассмотрю некоторые из этих основных функций адресации и их влияние в случаях маршрутизации – впрочем, статья Аарона останется полезной благодаря дополнительным сведениям об этих функциях WCF.

Как правило, клиенты отправляют сообщения напрямую целевой службе, используя прокси, созданный из описания службы. Чтобы клиент и служба были совместимыми, они разделяют эквивалентные контракты и настройки конечных точек. Рассмотрев контракт службы и настройку, показанные на рис. 1, можно вывести из них несколько важных требований к адресации для службы.

Рис. 1 Настройка конечной точки и контракт службы

Service Contract
[ServiceContract(Namespace =
"http://www.thatindigogirl.com/samples/2008/01")]
public interface IMessageManagerService
{
  [OperationContract]
  string SendMessage(string msg);

  [OperationContract]
  void SendOneWayMessage(string msg);
}
Endpoint Configuration
<system.serviceModel>
  <services>
   <service name="MessageManager.MessageManagerService"
    behaviorConfiguration="serviceBehavior">
    <endpoint
     address="http://localhost:8000/MessageManagerService"
     contract="MessageManager.IMessageManagerService"
     binding="basicHttpBinding" />
   </service>
  </services>
</system.serviceModel>

Во-первых, ожидаемый заголовок адресации Action («Действие») для запроса к операции SendMessage таков:

http://www.thatindigogirl.com/samples/2008/01/IMessageManagerService/SendMessage

Поскольку OperationContractAttribute не указывает Action, это значение выводится из пространства имен контракта службы, имени контракта (по умолчанию им становится имя интерфейса) и имени операции (по умолчанию им становится имя метода).

Во-вторых, ожидаемый заголовок Action для ответа от SendMessage таков:

http://www.thatindigogirl.com/samples/2008/01/IMessageManagerService/SendMessageResponse

Поскольку OperationContractAttribute не указывает ReplyAction, это значение производится тем же способом, что и свойство Action, с добавлением суффикса «Response» («Ответ»).

Наконец, ожидаемый заголовок To («Кому») для сообщений, целью которых является конечная точка службы, таков:

http://localhost:8000/MessageManagerService

Значение выводится из атрибута адреса для элемента конечной точки, который считается логическим адресом конечной точки. Физический адрес конечной точки обычно совпадает с логическим, хотя может быть указано иначе. Это означает, что клиенты обычно отправляют сообщения на физический адрес, соответствующий заголовку To.

Метаданные службы описывают эти требования, позволяя клиентам создать совместимые прокси и настройку. Контракт службы, созданный для клиента, отражает все те же параметры Action и ReplyAction службы, а настройка привязки клиента будет отражать конечную точку с соответствующим логическим и физическим адресом. Например, следующая конечная точка клиента совместима со службой на рис. 1:

<client>
  <endpoint 
   address="http://localhost:8000/MessageManagerService"
   binding="basicHttpBinding" 
   contract="localhost.IMessageManagerService" 
   name="basicHttp" />
</client> 

Прокси клиента использует свойство адреса элемента конечной точки клиента и для его логического, и для физического адреса. Как результат, сообщения обычно отправляются на физический адрес, соответствующий заголовку To («Кому»), как я указала раньше. Когда прокси вызывает операцию SendMessage, отправляется сообщение с заголовками To и Action, показанными на рис. 2.

Рис. 2 Сообщение, отправленное от прокси

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
   <To s:mustUnderstand="1"
    xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">
    http://localhost:8000/MessageManagerService
   </To>
   <Action s:mustUnderstand="1" 
    xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">
    http://www.thatindigogirl.com/samples/2008/01
     /IMessageManagerService/SendMessage
   </Action>
  </s:Header>
  <s:Body>
   <SendMessage xmlns="http://www.thatindigogirl.com/samples/2008/01">
    <msg>test</msg>
   </SendMessage>
  </s:Body>
</s:Envelope>

Сочетание заголовков To и Action, соответственно, указывает модели службы, какой диспетчер канала должен обработать сообщение и какую операцию диспетчер должен вызвать. По умолчанию, должна существовать конечная точка, логический адрес которой совпадает с заголовком To, а операция с заголовком Action. На рис. 3 показан этот поток.

 

Рис. 3 Типовая адресация без маршрутизатора

В следующих разделах я объясню значение логического и физического адреса, смысл заголовков To и Action, а также правила фильтрации сообщений при введении маршрутизатора в эту ситуацию.