Создание маршрутизатора WCF - Перенаправление сообщений
ОГЛАВЛЕНИЕ
Перенаправление сообщений
После того, как маршрутизатор получает сообщение и обрабатывает его в соответствии с собственными требованиями, он перенаправляет сообщение соответствующей подчиненной службе для дальнейшей обработки. Простая реализация маршрутизатора для описанного выше контракта показана на рис. 6. ProcessMessage конструирует канал клиента (или прокси) при помощи ChannelFactory<T> и использует этот прокси для пересылки сообщений определенной конечной точке службы, возвращая любые ответы.
Рис. 6 Реализация простого маршрутизатора
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class RouterService : IRouterService {
public Message ProcessMessage(Message requestMessage) {
using (ChannelFactory<IRouterService> factory =
new ChannelFactory<IRouterService>("serviceEndpoint")) {
IRouterService proxy = factory.CreateChannel();
using (proxy as IDisposable) {
return proxy.ProcessMessage(requestMessage);
}
}
}
}
Прокси обычно строго типизированы в контракте целевой службы, но в данном случае прокси должен быть способен перенаправить любое сообщение и получить любой ответ – контракт маршрутизатора способствует этому. В этом простом примере маршрутизатор просто перенаправляет первоначальное сообщение целевой службе и возвращает любой ответ. Если операция на целевой службе одностороння, ответ не отправляется.
Поскольку контракт работает с нетипизированными сообщениями, то же сообщение перенаправляется службе, как показано на рис. 7. Однако следует понять, что в сообщение внесено изменение, которое может оказаться неожиданным: заголовок To изменен перед отправкой сообщения службе.
Рис. 7 Адресация семантики через простой маршрутизатор
Вспомним, что по умолчанию прокси будет использовать логический адрес из своей настройки конечной точки, чтобы установить заголовок To для исходящих сообщений – даже если передан необработанный экземпляр Message, уже имеющий заголовок To. Это может показаться хорошей идеей (поскольку все службы требуют, чтобы заголовок To совпадал с логическим адресом одной из их конечных точек), но способно вызвать побочные эффекты. Например, если обновленный заголовок To не подписан, а у службы включена безопасность, то сообщение будет отвергнуто.
В идеале, клиент должен отправить сообщение с заголовком To, соответствующим целевой службе, маршрутизатор должен принять это сообщение, несмотря на несовпадение, и перенаправить его службе, не изменяя заголовок To. Этого можно добиться через настройки привязки, о которых я сейчас и расскажу.