[Из песочницы] WCF Служба маршрутизации — Часть I

Введение Служба маршрутизации является общим SOAP -посредником, которая выступает в качестве маршрутизатора. Базовая функциональность службы маршрутизации является возможность маршрутизации входящих сообщений на основе содержимого сообщения (в заголовке или теле сообщения) к фактическим служб, размещенных в том же компьютере, что и Router Service или распределенных по сети. На самом деле Служба маршрутизации действует как переднего плана обслуживания, который отражает целевую службу (ы). Основное преимущество в Routing Service является обеспечить прозрачность местоположения для клиента (приложения), так как клиент явно отделена от зная ничего о фактических услуг, которые фактически выполняют задачи от ее имени. Поэтому это дает возможность выполнять различные виды промежуточной обработки в рамках услуги маршрутизации.Вы можете использовать маршрутизацию в ряде направлений. например, вы можете использовать маршрутизацию для маршрутизации входящих сообщений на соответствующие услуги (ы) с помощью content-based/context-based методы маршрутизации. Вы также можете использовать маршрутизацию для реализации границу централизованной безопасности, протокол моста, балансировку нагрузки или даже службы версиями.

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

image

Понимание сервиса маршрутизации WCF 4.0 пришел с новым классом под названием RoutingService, который обеспечивает общий WCF реализации маршрутизации. RoutingService класс может обрабатывать маршрутизации сообщений по любому WCF, поддерживаемой протоколом, используя различные шаблоны сообщениями, как в одну сторону, запрос-ответ, и дуплексный обмен сообщениями. Этот класс находится под System.ServiceModel.Routing имен, и вы должны будете добавлять ссылку на System.ServiceModel.Routing.dll собраний в ваш хостинг применения.Ниже приводится определение RoutingService класса (от MSDN)

[AspNetCompatibilityRequirementsAttribute (RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehaviorAttribute (AddressFilterMode = AddressFilterMode.Any, InstanceContextMode = InstanceContextMode.PerSession, UseSynchronizationContext = ложь , ValidateMustUnderstand = ложь)] общественного запечатаны класс RoutingService: ISimplexDatagramRouter, ISimplexSessionRouter, IRequestReplyRouter, IDuplexSessionRouter, IDisposable {. …} Из вышесказанного видно, что RoutingService класс определяется как запечатанном класса и реализует несколько контрактов на обслуживание, с тем чтобы поддерживается несколько шаблонов обмена сообщениями (MEP). Каждый сервисный контракт обеспечивает поддержку другой обмена сообщениями рисунком (МООС). Пожалуйста, проходим таблицу внизу Подробнее (от MSDN) — IDuplexSessionRouter — Определяет интерфейс, необходимый для обработки сообщений от дуплексных сессии каналов.IRequestReplyRouter — Определяет интерфейс, необходимый для обработки сообщений от запрос-ответ каналов.ISimplexDatagramRouter — Определяет интерфейс, необходимый для обработки сообщений от простого дейтаграммы.ISimplexSessionRouter — Определяет интерфейс, необходимый для обработки сообщений от симплексных сессии каналов.

Обратите внимание, что ISimplexDatagramRouter и IRequestReplyRouter интерфейсы определяют общие односторонние и контрактной службы запрос-ответ определений, которые можно использовать в сочетании с контрактов на обслуживание бизнес-конкретные, а два других, ISimplexSessionRouter & IDuplexSessionRouter, интерфейсы сервисные контракты сессия требовательным. ISimplexSessionRouter в основном операция пожаро-и-забыл, что происходит в рамках сессии в то время как IDuplexSessionRouter в основном дуплекс сессия известно операция, которая должна перезвонить в клиентское приложение в сферу сессии. Просьба ознакомиться с определениями этих интерфейсов внизу-

[ServiceContract (пространство имен = » http://schemas.microsoft.com/netfx/2009/05/routing » , SessionMode = SessionMode.Allowed)] общественного интерфейс ISimplexDatagramRouter { [OperationContract (AsyncPattern = верно , IsOneWay = верно , Action = » * »)] IAsyncResult BeginProcessMessage (сообщение Сообщение, AsyncCallback обратного вызова, объект состояния); недействительными EndProcessMessage (IAsyncResult результат); } [ServiceContract (пространство имен = » http://schemas.microsoft.com/netfx/2009/05/routing » , SessionMode = SessionMode.Allowed)] общественного интерфейс IRequestReplyRouter { [OperationContract (AsyncPattern = верно , IsOneWay = ложь , Action = » * » , ReplyAction = » * »)] [GenericTransactionFlow (TransactionFlowOption.Allowed)] IAsyncResult BeginProcessRequest (сообщение Сообщение, AsyncCallback обратного вызова, объект состояния); Сообщение EndProcessRequest (IAsyncResult результат); } [ServiceContractAttribute (пространство имен = » http://schemas.microsoft.com/netfx/2009/05/routing » , SessionMode = SessionMode.Required)] общественного интерфейс ISimplexSessionRouter { [OperationContractAttribute (AsyncPattern = верно , IsOneWay = верно , Action = » * »)] IAsyncResult BeginProcessMessage (сообщение Сообщение, AsyncCallback обратного вызова, Object состояние); недействительными EndProcessMessage (IAsyncResult результат); } общественного интерфейс IDuplexSessionRouter { [OperationContractAttribute (AsyncPattern = верно , IsOneWay = верно , Action = » * »)] IAsyncResult BeginProcessMessage (сообщение Сообщение, AsyncCallback обратного вызова, Object состояние); недействительными EndProcessMessage (IAsyncResult результат ;) } Основной целью RoutingService класса для приема входящих сообщений от клиентских приложений через виртуальный конечной точки (ов) и » маршрут «их к соответствующей действительной эксплуатации путем оценки каждое входящее сообщение от набора фильтров сообщений. Таким образом, вы можете контролировать поведение маршрутизации, определяя фильтры сообщений, как правило, в файле конфигурации.

Хостинг маршрутизации службы Вы можете разместить на RoutingService как и другие WCF услуг с использованием собственного хостинга или управляемого хостинга методы. Ниже приведен типичный пример самостоятельной хостинг техники для проведения RoutingService помощью ServiceHost класс.Как и другие WCF услуг вы также можете настроить RoutingService через файл конфигурации, где вы определяете RoutingService конечную точку (ы), RoutingService Поведение, фильтры маршрутизации и фактических услуг конечную точку (ы), где, наконец, входящие сообщения будут разгромлены. Давайте попробуем понять, эти понятия в ближайшие разделах.Настройка маршрутизации конечной точки службы Вы можете настроить один или несколько RoutingService конечную точку (ы), выбирая WCF привязки и один из RoutingService поддерживается сервисных контрактов, реализуемые RoutingService класса, как описано выше (IRequestReplyRouter, ISimplexDatagramRouter, ISimplexSessionRouter, IDuplexSessionRouter).Ниже приведен пример RoutingService с двумя конечными точками маршрутизации.

Выше, в первую конечная точка использует BasicHttpBinding с IRequestReplyRouter контракта на оказание услуг (запрос-ответ) и второй конечная точка использует WSHttpBinding с ISimplexDatagramRouter контракта на оказание услуг (в одну сторону). Конечные точки настроенные выше, в основном маршрутизации конечные точки (виртуальные конечные точки или сообщение брокеры), которые будут использованы на клиентских приложений. Клиентские приложения могут использовать один из этих конечных точек для вызова фактические услуги, и каждый вызов службы будут направлены непосредственно на RoutingService. Когда RoutingService получает сообщение через один из этих конечных точек маршрутизации, он оценивает сообщение от набора фильтров сообщений, чтобы определить, где переслать сообщение.

Ниже приведен пример из конечных точек клиентского приложения на основе выше RoutingService конфигурации-

Настройка маршрутизации служба фильтр сообщений Вы можете настроить RoutingService с фильтров сообщений для управления маршрутизацией фильтры сообщений. WCF 4.0 поставляется с RoutingBehavior для того же. Так что для того, чтобы настроить RoutingService с фильтров сообщений, Вы должны определить именованный конфигурацию поведения (скажем » routingFilters »), включив RoutingBehavior затем, указав имя таблицы фильтра. После этого вам нужно применить » routingFilters поведение «в RoutingService через behaviorConfiguration атрибута. См. пример ниже

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

Определение маршрутизации пользования Фильтр Таблица Фильтр Таблица определяет логику маршрутизации во время выполнения. Вы можете определить записи таблицы фильтр вэлемент. Каждая запись вопределяет соответствие между маршрутизации » фильтр «и целевой конечной точки. Вы можете определить » фильтры «вэлемент. Каждыйзапись задает тип фильтра вместе со значением фильтра конкретных данных, например, действия, в XPath выражения, конечной точки маршрутизации имя и т.д.).Ниже приведен пример конфигурирования таблицу фильтра » RoutingData «с двумя фильтрами, которые Карт две конечные точки. Здесь EndpointName был использован тип фильтра.

Демо служба Теперь, после описания RoutingService, давайте понять через примеры. Я создал демо сервис- ComplexNumberCalculator для этой цели. Я определил один контракта данных комплекса и один контракта службы IComplexNumberand, а затем создал ComplexNumberCalculator обслуживание путем внедрения IComplexNumberand договор на обслуживание. Пожалуйста, ознакомьтесь с ниже код- [DataContract] public class Complex { [DataMember] public double Real;

[DataMember] public double Imaginary; }

[ServiceContract] public interface IComplexNumber { [OperationContract] Complex Add (Complex x, Complex y);

[OperationContract] Complex Subtract (Complex x, Complex y);

[OperationContract] Complex Multiply (Complex x, Complex y);

[OperationContract] Complex Divide (Complex x, Complex y);

[OperationContract] double Modulus (Complex x);

[OperationContract] double Argument (Complex x);

[OperationContract] Complex Conjugate (Complex x);

[OperationContract] Complex Recipocal (Complex x); }

public class ComplexNumberCalculator: IComplexNumber { public Complex Add (Complex x, Complex y) { Console.WriteLine («Invoked ComplexNumberCalculator Operation: Add»);

var z = new Complex ();

z.Real = x.Real + y.Real; z.Imaginary = x.Imaginary + y.Imaginary;

return z; }

public Complex Subtract (Complex x, Complex y) { Console.WriteLine («Invoked ComplexNumberCalculator Operation: Subtract»);

var z = new Complex ();

z.Real = x.Real — y.Real; z.Imaginary = x.Imaginary — y.Imaginary;

return z; }

public Complex Multiply (Complex x, Complex y) { Console.WriteLine («Invoked ComplexNumberCalculator Operation: Multiply»);

var z = new Complex ();

z.Real = x.Real * y.Real — x.Imaginary * y.Imaginary; z.Imaginary = x.Real * y.Imaginary + x.Imaginary * y.Real;

return z; }

public Complex Divide (Complex x, Complex y) { Console.WriteLine («Invoked ComplexNumberCalculator Operation: Divide»);

var z = new Complex ();

var modulusY = this.Modulus (y);

z.Real = (x.Real * y.Real + x.Imaginary * y.Imaginary) / (modulusY * modulusY); z.Imaginary = (x.Imaginary * y.Real — x.Real * y.Imaginary) / (modulusY * modulusY);

return z; }

public double Modulus (Complex x) { Console.WriteLine («Invoked ComplexNumberCalculator Operation: Modulus»);

var modX = Math.Sqrt (x.Real * x.Real + x.Imaginary * x.Imaginary);

return modX; }

public Complex Conjugate (Complex x) { Console.WriteLine («Invoked ComplexNumberCalculator Operation: Conjugate»);

var z = new Complex ();

z.Real = x.Real; z.Imaginary = -1 * x.Imaginary;

return z; }

public double Argument (Complex x) { Console.WriteLine («Invoked ComplexNumberCalculator Operation: Argument»);

var argumentX = Math.Atan (x.Imaginary/x.Real);

return argumentX; }

public Complex Recipocal (Complex x) { Console.WriteLine («Invoked ComplexNumberCalculator Operation: Recipocal»);

var z = new Complex ();

var modulusX = this.Modulus (x); var conjugateX = this.Conjugate (x);

z.Real = conjugateX.Real / (modulusX * modulusX); z.Imaginary = conjugateX.Imaginary / (modulusX * modulusX);

return z; } Служба маршрутизации с использованием MatchAll FilterType В этом примере я собираюсь настроить простой RoutingService, что будет просто пройти (маршрут) все входящие сообщения с нашего ComplexNumberCalculator клиентского приложения службы в ComplexNumberCalculator службы. Здесь RoutingService просто выступать в качестве посредника. Я прошел RoutingService в окна консольного приложения с помощью само-хостинг технику. Вы можете разместить RoutingService в IIS / WAS / Windows Service / AppFabric согласно вашей потребности.Впервые я настроив RoutingService с следующей конечной точки (виртуальный конечная точка), как показано ниже-

Обратите внимание, что здесь я использовал IRequestReplyRouter договор на обслуживание как наш ComplexNumberCalculator сервис поддерживает запрос-ответ MEP.

Тогда я определил конечную точку для нашей целевой службы: ComplexNumberCalculator как ниже-

Следующая я позволил RoutingBehavior затем, указав имя таблицы фильтра. Я сделал это, определив поведение по умолчанию, как показано ниже-

Следующим шагом будет определить наш фильтр таблицу: RoutingTable на добавление элементов в нем. Но, как каждая запись в таблице фильтра определяет отображение между фильтром маршрутизации и целевой конечной точки, мы определим фильтры сначала тогда наш Filer таблицу. Я определил следующий фильтр для нашего фильтра таблицы-

… Я использовал выше MatchAll типа фильтра, который соответствует все входящие сообщения. Обратите внимание, что нашей целью является просто передать все входящие сообщения от клиента к ComplexNumberCalculator.

Наконец я настроив фильтр таблицу: RoutingTable с типом фильтра, определенного выше ниже-

Выше я добавил одну запись таблицы и установить FILTERNAME приписывать » ComplexNumberFilter »(имя типа фильтра, определенного выше) и endpointName приписывать » ComplexNumber »(название конечной точки целевой службы, конечным получателем).

Наконец, я создал консоль клиентское приложение для вызова службы. Я генерируется ComplexNumberCalculator код служба файл с помощью svcutil.exe из командной строки

svcutil.exe HTTP: / / локальный: 8081/ComplexNumberService/mex

и настройки на стороне клиента конечную точку, как показано ниже-

Обратите внимание, что я использовал здесь контракта службы IComplexNumber (из ComplexNumberCalculator servcie) вместо IRequestReplyRouter (из RoutingService). IComplexNumber контракт на оказание услуг будет использоваться для вызова ComplexNumberService операции, создав боковой канал клиента. Ниже приведен код-клиентское приложение

var cf = new ChannelFactory(«BasicHttpBinding_IComplexNumber»);

var channel = cf.CreateChannel ();

var z1 = new Complex (); var z2 = new Complex ();

z1.Real = 3D; z1.Imaginary = 4D;

z2.Real = 2D; z2.Imaginary = -2D;

Console.WriteLine (»*** RoutingService with Message Filters ***\n»); Console.WriteLine («Please hit any key to start:»); string command = Console.ReadLine ();

while (command!= «exit») { ComplexNumberArithmetics (channel, z1, z2);

Console.WriteLine (»\nPlease hit any key to re-run OR enter 'exit' to exit.»); command = Console.ReadLine (); }

((IClientChannel)channel).Close (); Метод ComplexNumberArithmetics выполняет комплексное число арифметику, используя канал, созданный выше (вы можете найти код ComplexNumberArithmetics метода в образце).

Есть четыре проекта в растворе: CalculatorService, ConsoleClient, ConsoleHostComplexNo & ConsoleHostRouter. Теперь набор ConsoleClient, ConsoleHostComplexNo & ConsoleHostRouter проектов как проектов Start Up и ударил Ctrl + F5 ключи, чтобы начать проекты. Теперь нажмите любую клавишу на консоли клиента, и вы можете убедиться, что маршрутизация работает нормально. Вы можете видеть, что сообщения приходят на ComplexNumberService после их » разгромили «посреднической RoutingService.

imageimageimage

На базе контента маршрутизации В методов маршрутизации на основе содержимого, целевая служба определяется путем оценки содержания определенного входящего сообщения. Вы можете оценить входящее сообщение заголовок или тело, чтобы решить конечную цель службы. Вы можете проверить SOAP действие входящего сообщения или некоторого значения внутри своей нагрузке, такие как элемент, атрибут или значению заголовка и т.д. можно использовать Action, XPath filterTypes реализовать контента на основе маршрутизации.imageДавайте рассмотрим пример, чтобы понять маршрутизации контента на основе с нашим ComplexNumberCalculator службы. Предположим, что мы хотим для маршрутизации бинарными операциями (сложение, вычитание, умножение и деление), чтобы ComplexNumberCalculator1 и унарные операции (Модуль, аргумент, сопряженных и взаимном) в ComplexNumberCalculator2.

Я реализовать то же самое двумя способами; Первый с помощью различных ComplexNumberCalculator значения действий в SOAP заголовка и, во-вторых, используя выражения XPath.

Вывод Маршрутизация в WCF является очень широкая тема. Я уже рассказывал WCF Служба маршрутизации концепцию и объяснил, как настроить RoutingService (конечной точки (ы), целевой услуги (услуг), сообщение фильтр (ы) и таблицу фильтр) в этой должности. Тогда я продемонстрировал простой RoutingService используя MatchAll FilterType и, наконец, изучить маршрутизацию на основе контента, используя Action ценности и XPath выражений. Но много, чтобы покрыть. В следующей серии этой статье я расскажу о некоторых маршрутизации темы, как протокол моста, основанной на контексте маршрутизации, балансировки нагрузки и т.д. до тех пор, счастлив кодирования.

© Habrahabr.ru