Создание маршрутизатора 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, а также правила фильтрации сообщений при введении маршрутизатора в эту ситуацию.