Создание маршрутизатора WCF - Заголовки MustUnderstand

ОГЛАВЛЕНИЕ

Заголовки MustUnderstand

Пока что речь шла о простой реализации маршрутизации, позволяющей проиллюстрировать вещи, которые следует принимать во внимание при разработке ядра маршрутизатора и которые также влияют на настройку адресации, фильтрации и привязки. Это простое решение маршрутизации работает, только если служба не включает безопасность, надежные сеансы или любой другой полнофункциональный протокол для ее привязок. На рис. 10 показано упрощенное представление протоколов привязки, о которых пока идет речь.

 

Рис. 10 Service Contract и Endpoint Configuration

На рис. 11 показано то же представление для сквозного маршрутизатора, где служба требует безопасности и надежных сеансов. Включение этих протоколов значит, что клиент и каналы службы будут обмениваться дополнительными сообщениями для установки сеансов, запроса маркеров безопасности и прочего. Поскольку маршрутизатор пропускает все сообщения, данные сообщения, относящиеся к определенному протоколу, также будут переданы службе – и это хорошо.

 

Рис. 11 Сквозная конфигурация с безопасными сессиями

Однако когда сообщения службе и от службы включают заголовки, которые должны быть поняты получателем, возникает проблема. Поскольку у сквозного маршрутизатора не включена безопасность или надежные сеансы, эти каналы отсутствуют и не могут обрабатывать заголовки связанного протокола.

Службе маршрутизатора можно приказать игнорировать заголовки MustUnderstand, установив свойство ValidateMustUnderstand атрибута ServiceBehaviorAttribute на false, как показано тут:

[ServiceBehavior(InstanceContextMode = 
  InstanceContextMode.Single, 
  ConcurrencyMode = ConcurrencyMode.Multiple, 
  AddressFilterMode=AddressFilterMode.Any, 
  ValidateMustUnderstand=false)]
public class RouterService : IRouterService 

Это решит проблему со входящими сообщениям от клиента, но не с сообщениями, возвращенными подчиненными службами.

Для решения этой проблемы необходимо также изменить реализацию маршрутизатора, чтобы указать подобное поведение при инициализации фабрики каналов для вызова подчиненной службы, вот так:

using (ChannelFactory<IRouterService> factory = 
  new ChannelFactory<IRouterService>("serviceEndpoint"))
{
  factory.Endpoint.Behaviors.Add(new MustUnderstandBehavior(false));
  IRouterService proxy = factory.CreateChannel();
  
  // remaining code

Теперь протокол и сообщения службы могут свободно протекать между клиентом и службой через маршрутизатор, предполагая, что используется протокол HTTP.

Другая проблема возникает при применении дуплексных протоколов, таких как TCP, либо именованных каналов. Это значит, что сообщения могут быть инициализированы службой на клиенте, скажем при включении надежных сеансов. Существует усовершенствованная настройка маршрутизатора, которую можно использовать для решения этого специального случая.