Реализация IDuplexSessionChannel для перехвата и замены сообщений - PullRequest
2 голосов
/ 31 марта 2012

Я хотел бы перехватить сообщения WCF на стороне клиента. Я не могу использовать любой MessageInspector для этого, потому что я хотел бы реализовать клиентский кэш WCF. Если запрос был кеширован ранее, ответ должен поступить из кеша, в противном случае запрос перенаправляется в службу.

Поскольку я использую netTcpBinding и netNamedPipeBinding, «простой» способ реализации IRequestChannel невозможен. Мне нужно реализовать IDuplexSessionChannel. Сейчас я ищу рабочий образец, как перехватывать и заменять сообщения.


Но почему это важно?

Теоретически WCF-сервисы, как и все другие вызовы, которые, возможно, идут по сети, должны иметь грубые интерфейсы. Причина очевидна: WCF обладает множеством функций для защиты соединения, включения надежного обмена сообщениями, проверки подлинности, включения транзакций (... продолжение ...). Это не придет бесплатно, очевидно.

На практике мы часто сталкиваемся с "изъятиями" из этих правил. Услуги, которые называются тысячи раз в одном методе обслуживания и других нарушениях лучших практик. Ну, конечно, лучший способ справиться с этой ситуацией - изменить дизайн сервисов. К сожалению, такое случается редко (вы называете причины ...).

Именно здесь кеширование вступает в игру. Есть два основных способа сделать это:

  1. Реализация решения, которое должно переписать части ваших приложений. Один из способов сделать это - написать прокси-вызывающий объект (например, для этого использовать дженерики).
  2. Элемент списка

Реализация «прозрачного» решения, работающего со всеми WCF-сервисами, без каких-либо модификаций

По понятным причинам второе решение кажется более перспективным. Опять же, есть две альтернативы:

  1. Написание серверного кэширующего решения с использованием поведения WCF и IOperationInvoker. Это довольно просто сделать, и Интернет дает вам несколько хороших примеров, как это сделать. Например, решение приемлемо, если кэшируемый сервис довольно дорог в своих методах, например загрузка большого количества информации из базы данных, так что поиск результата в вашем кэше намного быстрее, чем выполнение всех необходимых вычислений и операций ввода-вывода. Тем не менее, WCF-вызов все еще там, со всеми накладными расходами, которые идут с ним. Преимущество заключается в том, что вам нужно определить это поведение только один раз в вашей службе, и все клиенты этой службы получат выгоду от кеша.
  2. Запись решения для кэширования на стороне клиента , которое предотвращает вызов WCF, если ответ уже находится в кэше. Это, конечно, предотвращает все накладные расходы WCF, но требует определения поведения (конечной точки) во всех клиентах, которые обращаются к службам, которые должны быть кэшированы (например, любая служба основных данных или любые другие службы «медленно меняющегося измерения»).

Второе решение намного сложнее, так как вам нужна фабрика каналов (и / или слушатель) и реализация самого канала. Канал может быть IRequestChannel или IDuplexSessionChannel. Опять же, вы найдете рабочее решение для первого типа в Интернете, но это, естественно, не будет работать для netTcpBining или netNamedPipeBinding, который использует IDuplexSessionChannel. Именно поэтому я ищу образец, который иллюстрирует, как сделать это правильно.

Просто чтобы составить представление о преимуществах: Одно решение с длительным методом обслуживания, время выполнения которого составляет (около 150000 вызовов других служб в этой службе):

  • netTcpBinding, без кэширования: 65 минут
  • netNamedPipeBinding, без кэширования: 40 минут
  • netNamedPipeBinding, кэширование на стороне сервера: 27 минут
  • netNamedPipeBinding, кэширование на стороне клиента: 19 минут

Нет. количество вызовов падает с 150000 до 40000 в этом сценарии. Однако мое решение для кэширования на стороне клиента не будет работать хорошо для дуплексных каналов и других специальных типов связи. Поэтому я ищу образец.

Любая помощь будет оценена.

...