Windows communication foundation что это

Обновлено: 05.07.2024

По крайней мере, так должно быть. На практике добавление нового сервиса — это рутина. Нужно не забыть прописать конфигурацию на сервере, сделать то же самое на клиенте, нужно написать или сгенерировать proxy-класс. Поддерживать конфиги неудобно. Если сервис изменился, то нужно вносить изменения в proxy-класс. А ещё не забыть про регистрации в IoC-контейнере. И добавление новых хостов для новых сервисов. И еще хочется простой асинхронности. По отдельности всё просто, но даже для статьи я дописывал этот список уже трижды, и не уверен, что не упустил чего-нибудь.

Quick start

Создадим клиент-серверное приложение. Клиенты передают серверу индекс числа из последовательности Фибоначчи, сервер возвращает число из последовательности с заданным индексом. Из кода в статье убрано логирование и обработка ошибок, но в коде на github я привожу более полный пример для иллюстрации целостного подхода.
Структура проектов, приближенная к реальности:


Server.Contracts содержит интерфейсы wcf-сервисов, Server — их реализацию, а так же реализацию хостера — класса, который будет поднимать wcf-сервисы. BL — логика сервера. ConsoleServiceHost хостит сервисы в домене консольного приложения. Client.Presentaion содержит соответствующий слой клиента. В нашем примере там только команда вызова сервиса и обработка результата. Client — консольное приложение, использующее предыдущую сборку для обработки ввода пользователя.

  • Rikrop.Core.Wcf.Unity содержит хелперы для регистрации в IoC-контейнере инфраструктуры, необходимой для работы wcf. Это набор готовых решений и расширений для быстрой настройки всех аспектов взаимодействия. Пакет следует добавить в проекты, где будут серверные и клиентские регистрации в IoC-контейнере. У нас это RikropWcfExample.Server и RikropWcfExample.Client.
  • Rikrop.Core.Wcf содержит основные классы по работе с wcf, управлению каналом, сессиями, авторизацией, хостинга wcf-сервисов. Его добавим в RikropWcfExample.Server, там будет лежать хостер, и RikropWcfExample.Client.Presentation*, откуда будет происходить вызов wcf-сервиса.


Реализация в CalculatorService.cs будет передавать запрос и возвращать результат из слоя бизнес-логики:


Пока можно заметить одну особенность — wcf-сервис использует async/await для описания асинхронности. В остальном никаких специфических конструкций нет.

Теперь перейдем к регистрации. Простейший синтаксис для сервера указывает тип привязки (NetTcp) список поведений, которые должны быть добавлены к сервисам:


Для клиента указывается тип обёртки-исполнителя для сервисов (ServiceExecutor), тип обёртки над привязкой (Standart предполагает NetTcp) и, собственно, адрес сервера:


Всё. Не нужно регистрировать каждый сервис по интерфейсу, не нужно создавать Proxy, не нужно прописывать wcf в конфигурации — эти регистрации позволят сразу начать работать с сервисами так, будто это локальные вызовы.
Но сначала нужно захостить их на сервере. Библиотека Rikrop.Core.Wcf уже включает класс ServiceHostManager, который сделает всю работу самостоятельно. Прописывать каждый сервис не нужно:


Сравнение с классическим подходом и расширяемость

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

Добавление нового метода в существующий wcf-сервис или изменение сигнатуры существующего метода
  • В ServiceContract добавить определение метода.
  • В классе wcf-сервиса добавить реализацию.
  • В ServiceContract добавить определение метода.
  • В классе wcf-сервиса добавить реализацию.
  • Сгенерировать proxy-класс на клиенте или добавить ручную реализацию вызова нового сервиса на клиенте (иногда оба варианта, если не хочется напрямую использовать proxy-класс.
Добавление нового wcf-сервиса в существующий хост
  • Создать ServiceContract нового сервиса.
  • Реализовать контракт сервиса.
  • Создать ServiceContract нового сервиса.
  • Реализовать контракт сервиса.
  • Сгенерировать proxy-класс на клиенте или добавить ручную реализацию вызова нового сервиса на клиенте (иногда оба варианта, если не хочется напрямую использовать proxy-класс.
  • Добавить в хост wcf код, инициализирующий ServiceHost для нового сервиса.
  • Зарегистрировать вклиентском IoC-контейнере Proxy-класс нового сервиса.
  • Добавить конфигурацию сервиса на сервере и не клиенте.
Изменение настроек всех wcf-сервисов (на примере типа привязки)
  • В серверной регистрации изменить строку с типом привязки*.
  • В клиентской регистрации изменить строку с типом тип привязки*.
  • В app.config сервера изменить все записи в блоке <bindings>*.
  • В app.config клиента изменить все записи в блоке <bindings>*.
Изменение настроек нескольких wcf-сервисов (на примере типа привязки)
  • На сервере добавить регистрацию для нового адреса и типа привязки.
  • В клиентской регистрации добавить новую регистрацию для другого адреса и типа привязки.
  • В app.config сервера изменить записи в блоке <bindings> для нужных wcf-сервисов.
  • В app.config клиента изменить записи в блоке <bindings> для нужных wcf-сервисов.
Расширяемость. Behavior для авторизации и работы с сессиями


Можно изменить способ авторизации, добавив свою имплементацию System.ServiceModel.ServiceAuthorizationManager, изменить способ инициализации идентификатора сессии, метод проверки авторизации, способ извлечения сессии из контекста выполнения запроса, способ хранения и копирования сессий на сервере. В обобщенном случае регистрация AuthorizationBehavior может выглядеть следующим образом:


Клиентская регистрация так же меняется:


Алгоритм работы

    Клиент авторизуется через выбранный метод в wcf-контракте. При успешной аутентификации сервер создаёт сессию, сохраняет её в репозитории и отдаёт данные о ней клиенту:

получает данные о сессии и сохраняет их:

Что внутри

Большую часть инфраструктуры предоставляет библиотека System.ServiceModel.dll. Однако, есть несколько решений, которые нужно рассмотреть подробнее.

Основой взаимодействия между клиентом и сервером служат реализации интерфейса IServiceExecutor, находящиеся в библиотеке Rikrop.Core.Wcf.


В простейшем случае открывается канал и метод вызывается в контексте этого канала:


Более сложные реализации могут конвертировать ошибки или дополнительно извещать об окончании обработки изменением свойства. Наибольшее распространение эти идеи получили в WPF-реализациях IServiceExecutor, где с помощью ServiceExecutorFactory можно создать обёртки над wcf-сервисом, позволяющие использовать DataBinding для оповещения UI о продолжительной операции, или отображающие popup с произвольной информацией во время ожидания ответа от сервера.
Для легкой реализации главную роль играют Fluent interface при регистрации и стандартные реализации инфраструктуры библиотеки, из-за чего даже даже в самых сложных конструкциях легко разобраться с первого раза с помощью подскзок студии:


Итоги

Единожды настроив инфраструктуру на проекте, можно надолго забыть о сетевой природе взаимодействия через IServiceExexutor. Лучше всего применять системный подход и использовать так же бибилиотки для построения настольных приложений с применением mvvm-паттерна, взаимодействия с БД, логирования и других типовых задач. Но даже при нежелании использовать незнакомый и не всегда привычный фреймворк, можно найти применение идеям, лежащим в его основе. Расширяемость компонент, строгая типизация при конфигурировании, прозрачность взаимодействия на всех слоях, минимизация инфраструктурного кода и затрат времени на поддержание инфрастурктуры — это то, о чём важно не забывать при написании калькулятора и многопользовательской Enterprise-системы. Можно скачать код библиотек и подключить их к решению проектом вместо использования библиотеки. Это позволит изучить работу под отладчиком и при необходимости внести свои изменения.

Бонус

Нет ничего лучше практики. Я узнал, что у нас был опыт перевода довольно крупного проекта (

Еще есть решение для wpf с информированием пользователя через блокировку ui или всплывающие окна, реализованные через ServiceExecutorFactory. Это частный пример и он относится куда больше к wpf, чем к wcf. Но это может дать больше информации о преимуществах библиотеки и мотивации к использованию.

Интеграция WCF с другими технологиями Майкрософт

WCF — это гибкая платформа. Из-за такой крайней гибкости WCF также используется в нескольких других продуктах Майкрософт. Зная основы WCF, вы получаете мгновенное преимущество, если вы также используете любой из этих продуктов.

первая технология, связанная с WCF, была Windows Workflow Foundationом (WF). Рабочие процессы упрощают разработку приложений, инкапсулирующие шаги в рабочем процессе как "действия". в первой версии Windows Workflow Foundation разработчику пришлось создавать узел для рабочего процесса. следующая версия Windows Workflow Foundation была интегрирована с WCF. Это позволяло легко размещать любой рабочий процесс в службе WCF. это можно сделать, автоматически выбрав тип проекта WF/WCF в Visual Studio 2012 или более поздней версии.

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

возможности размещения сервера приложений Windows server AppFabric специально разработаны для развертывания приложений, использующих WCF для обмена данными, и управления ими. Функции размещения включают разнообразные средства и параметры конфигурации, специально разработанные для приложений с поддержкой WCF.

Основы WCF

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

Протоколы связи

кодировка текста - кодирование с возможностью взаимодействия;

двоичное кодирование для эффективной передачи.

Дополнительные механизмы кодирования (например, кодирование сжатия) можно добавить с помощью встроенных точек расширения WCF.

Основные понятия Windows Communication Foundation

в этом документе представлено высокоуровневое представление архитектуры Windows Communication Foundation (WCF). В нем приводится объяснение ключевых понятий и их взаимосвязь. Руководство по созданию простейшей версии службы WCF и клиента см. в руководстве по начало работы. Дополнительные сведения о программировании WCF см. в разделе Базовая программирование WCF.

Что такое Windows Communication Foundation

Защищенная служба для обработки бизнес-транзакций.

Служба, передающая другим объектам текущие данные, такие как отчет о трафике, или другая служба наблюдения.

Служба бесед, которая позволяет двум пользователям общаться и обмениваться данными в реальном времени.

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

Предоставление доступа к рабочему процессу, реализованному с помощью Windows Workflow Foundation, в виде службы WCF.

Приложение Silverlight для запроса последних каналов данных в службе.

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

Возможности WCF

В состав WCF входит следующий набор функций. Дополнительные сведения см. в разделе сведения о функции WCF.

Сервис-ориентированность

Одним из последствий использования стандартов WS является то, что WCF позволяет создавать приложения, ориентированные на службы . Сервисноориентированная архитектура (SOA) подразумевает применение веб-служб для отправки и получения данных. Общим преимуществом служб является слабая связанность вместо жесткой запрограммированности для различных приложений. Слабая связь означает, что любой клиент, созданный на любой платформе, может подключаться к любой службе при условии, что выполняются необходимые контракты.

Совместимость

WCF реализует современные отраслевые стандарты для взаимодействия веб-служб. Дополнительные сведения о поддерживаемых стандартах см. в статье взаимодействие и интеграция.

Метаданные службы

Контракты данных

Безопасность

Несколько транспортов и кодировок

Транзакции

WCF также поддерживает транзакции с использованием одной из трех моделей транзакций: WS-Атомиктрансактионс, API-интерфейсы в System.Transactions пространстве имен и Microsoft координатор распределенных транзакций. Дополнительные сведения о поддержке транзакций в WCF см. в разделе транзакции.

Поддержка AJAX и REST

REST - это пример развития технологии Web 2.0. WCF можно настроить для обработки «обычных» XML-данных, которые не упакованы в конверт SOAP. Кроме того, WCF можно расширить для поддержки конкретных форматов XML, таких как ATOM (популярный RSS-стандарт), и даже для форматов, отличных от XML, таких как нотация объектов JavaScript (JSON).

Расширяемость

Архитектура WCF имеет ряд точек расширения. Если требуются дополнительные возможности, поддерживаются точки входа, посредством которых можно настроить поведение службы. Дополнительные сведения о доступных точках расширения см. в разделе Расширение WCF.

Пример создания WCF-сервиса, работающего внутри службы Windows

Windows Communication Foundation – программная платформа от Microsoft для создания, настройки и развертывания распределенных сетевых сервисов. WCF-runtime и его пространство имен System.ServiceModel, представляющее его главный программный интерфейс, это преемник технологий создания распределенных систем, успешно применяемых разработчиками для создания распределенных приложений на платформе Windows в последнее десятилетие. Разберём тестовый пример создания WCF-сервиса.

Открываем Visual Studio 2015 и создаём новый проект типа Class Library. Проект назовём WCFMyServiceLibrary.



Файл Class1.cs переименуем в MyService.cs и добавим ещё один класс, файл для которого назовём IMyService.cs.

Добавим ссылку на сборку System.ServiceModel.

В файле MyService.cs опишем реализацию интерфейса:

На этом разработка сервиса завершена. Переходим к созданию службы Windows, которая будет контейнером для данного сервиса.

В том же решении (Solution) создадим новый проект типа «Служба Windows». Называем проект WindowsServiceHostForMyService.


Затем файл Service1.cs (только что созданного проекта) переименуем в MyService.cs. В этот проект добавим ссылку на сборку System.ServiceModel, а также не забываем указывать в файле MyService.cs директивы:


В классе MyService добавляем новый член:


Также необходимо добавить ссылку на проект WCFMyServiceLibrary, который находится в этом же решении:


Затем в классе MyService изменим метод OnStart таким образом, чтобы в этом методе добавлялись конечные точки нашего сервиса (endpoint):

Затем реализуем остановку сервиса в методе OnStop:


Затем в Обозревателе решения — двойной клик на файле MyService.cs (проекта WindowsServiceHostForMyService) откроет этот файл в режиме конструктора (Design Mode).


На пустом пространстве вызываем контекстное меню (щелчок правой кнопкой мыши) и выбираем «Добавить установщик».


При этом будет создан новый класс ProjectInstaller.cs
Переименуем файл ProjectInstaller.cs в MyServiceInstaller.cs.
При этом выйдет окно с вопросом, следует ли переименовать зависимые объекты – отвечаем «Да».

Добавим в файл ссылку


Затем изменим код конструктора класса MyServiceInstaller:


Заметим, что вызов метода InitializeComponent() мы заблокировали с помощью комментария.
На этом разработка службы Windows завершена. Собираем всё решение (Build Solution) и переходим к следующему этапу – установка службы Windows.

Для установки нашей службы создадим bat-файл (с произвольным названием, например Install_Windows_Service.bat) следующего содержания:


Нужно скопировать этот bat-файл в ту же папку, где находится скомпилированный файл WindowsServiceHostForMyService.exe (вам нужно заранее продумать, в какой папке будет лежать этот файл, который будет всегда запущен в качестве службы Windows).

Запускаем bat-файл, после чего наша программа WindowsServiceHostForMyService.exe будет установлена в качестве службы Windows.

Запустим эту службу с помощью стандартной программы управления службами.

Следующий этап – разработка клиентского приложения для использования предоставляемых сервисом услуг.

Для этого прежде всего нужно организовать так называемый «переходник» — Service Proxy – набор настроек, описывающих сервис для клиентского приложения.

Воспользуемся для этого стандартной утилитой SvcUtil.exe. Создадим файл Generate_Proxy.bat следующего содержания


Запустим этот файл (стандартная утилита SvcUtil.exe находится в папке C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin).

Этот файл нужно запустить во время работы нашего сервиса, т.е. в данном случае, после успешного запуска службы Windows WindowsServiceHostForMyService.

В случае успешного запуска, программа SvcUtil.exe сгенерирует 2 файла — MyServiceProxy.cs и App.config.

Эти файлы необходимо добавить для клиентского приложения, чтобы это приложение могло вызывать методы нашей службы (чуть ниже вы узнаете, что файл App.config я решил не добавлять — обойдёмся и без него).

Примечание. Аналогичного результата можно было добиться, запустив

В том же решении (Solution) создадим обычное приложение Windows Forms. Назовем его WindowsFormsApplication1


Добавим в этот проект ссылку на System.ServiceModel и, конечно же,


Добавим в этот проект файл MyServiceProxy.cs (именно его мы сгенерировали утилитой SvcUtil.exe). При этом следует добавить в файл MyServiceProxy.cs следующие строки:


После этого, мы сможем ссылаться на класс MyServiceClient (этот класс создан программой SvcUtil.exe), указав в файле формы директиву.

Пример готового файла MyServiceProxy.cs (комментарии удалены):

Поступим неординарно – и не будем добавлять файл App.Config в проект клиента!

Кнопка btn_Start – создаёт клиента
Кнопка btn_Send – отправляет сервису текстовую строку из текстового поля
Кнопка btn_Close – удаляет клиента из памяти и закрывает приложение


Заметим, что в данном примере на клиенте мы совсем не использовали конечную точку

Термины WCF

Другие понятия и термины, используемые в документации по WCF, включают следующее:

Message
Автономная единица данных, которая может состоять из нескольких частей, включая текст и заголовки.

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

Служба WCF видима внешнему миру как коллекция конечных точек.

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

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

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

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

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

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

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

Размещение
Служба должна быть размещена в некотором процессе. Узел — это приложение, которое управляет временем существования службы. Службы могут быть резидентными (размещенными сами в себе) или управляемыми существующим ведущим процессом.

Автономная служба
Служба, которая выполняется в приложении-процессе, созданном разработчиком. Разработчик контролирует время существования службы, набор свойств службы, открывает службу (при этом служба переходит в режим ожидания данных) и закрывает службу.

Instancing
Со службой связана модель создания экземпляров. Существуют три модели создания экземпляров: «один экземпляр», в которой один объект CLR обслуживает всех клиентов, «по вызовам», в которой для обработки каждого вызова, поступившего от клиента, создается новый объект CLR, и «по сеансам», в которой создается набор объектов CLR, по одному на каждый отдельный сеанс. Выбор модели создания экземпляров зависит от требований к приложению и ожидаемого режима использования службы.

Канал
Конкретная реализация элемента привязки. Привязка представляет собой конфигурацию, а канал является реализацией, связанной с этой конфигурацией. Следовательно, с каждым элементом привязки связан канал. Каналы, собранные в стек друг на другом, образуют конкретную реализацию привязки: стек каналов.

Клиент WCF можно создать автоматически с помощью средства служебной программы метаданных ServiceModel (Svcutil.exe) и указать его в работающей службе, которая публикует метаданные.

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

Метаданные, предоставляемые службой, содержат документы схемы XML, определяющие контракт данных службы, и документы WSDL, описывающие методы службы.

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

Протокол*
Сокращение для обозначения растущего набора спецификаций веб-служб (WS), таких как WS-Security, WS-ReliableMessaging и т. д., реализованных в WCF.

Читайте также: