Главная » Silverlight » Дуплексные службы

0

Обычно в службах используется довольно прямолинейный и ограниченный способ взаимодействия. Клиент {приложение Silverlight) передает запрос, ждет ответа, а затем обрабатывает ответ. Это односторонняя коммуникация. Клиент инициирует каждый се­анс взаимодействия.

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

•       Упорядоченный опрос (polling). Разработчик создает клиентскую программу, ко­торая периодически устанавливает соединение с сервером и проверяет наличие новых данных. Например, для комнаты чатов можно создать клиентскую програм- му, которая раз в секунду обращается к серверу за новыми сообщениями. Наиболее очевидная проблема опроса — неэффективность. На стороне клиента накладные расходы минимальные, однако канал сервера легко может оказаться закупоренным большим количеством клиентов, непрерывно бомбардирующих сервер запросами.

•       Сокеты (sockets). Наиболее мощный способ двусторонней коммуникации осно­ван на использовании сокетов — низкоуровневых сетевых соединений. Протокол HTTP в сокетах вообще не используется. Вместо него применяется более "чистый" и эффективный протокол TCP. Однако использование сокетов — очень сложная задача. Для ее решения нужно учесть ограничения времени, организовать масси­вы байтов, обеспечить синхронизацию пользователей и т.д. В главе 20 приведен пример приложения, в котором используются сокеты.

•       Дуплексная служба. Платформа Silverlight предоставляет средства созда­ния дуплексных служб, обеспечивающих двустороннюю коммуникацию (это означает, что сервер при необходимости сам инициирует контакт с клиентом). Дуплексная служба фактически базируется на упорядоченном опросе, организо­ванном значительно эффективнее. Сетевой запрос клиента остается открытым, но в неактивном состоянии, благодаря чему не загружается канал сервера. За­прос открыт длительное время, например 90 секунд, после чего он закрывается и клиентская программа вновь устанавливает соединение.

были доступны и в Silverlight 2, однако в этой версии они были разработаны как оценочное средство, довольно сложное и слабо поддерживаемое плат­формой Silverlight. В Silverlight 3 дуплексные службы поддерживаются полностью. Они по-прежнему используются редко, но это интересная технология, облегчающая перио­дические обновления и выполнение длительных операций. В следующих разделах в ка­честве примера обсуждается создание простой дуплексной службы, обрабатывающей пакетное задание. При ее использовании клиент передает запрос, а сервер асинхронно обрабатывает его и возвращает готовый продукт клиенту.

Конфигурирование дуплексной службы

Начало создания дуплексной службы такое же, как и обычной: добавление в проект Silverlight службы WCF. В данном примере служба имеет имя AsyncTask. svc.

При добавлении новой службы программа Visual Studio создает три знакомых вам компонента.

•       Файл . svc. Является конечной точкой службы. Клиентское устройство направ­ляет по его адресу все сообщения. В данном примере файл имеет имя AsyncTask. svc. Вам не нужно модифицировать его.

•       Код службы. Для дуплексной службы сгенерированный код не очень полезен. В следующих разделах вы его откорректируете.

•       Конфигурационный файл web. conf ід. Для поддержки дуплексной коммуни­кации его нужно немного настроить. Эту операцию рекомендуется выполнить в первую очередь.

Ниже описаны изменения, которые необходимо внести в автоматически сгенери­рованный файл web. conf ід для преобразования обычной службы в дуплексную. Файл web. conf ід можно найти в кодах примеров для данной главы.

Сначала добавьте в проект ссылку на сборку System. ServiceModel. PollingDuplex. dll, необходимую для поддержки дуплексной службы. Эта сборка находится в папке С:\Program Files\Microsoft SDKs\Silverlight\v3.OXOLibrariesXServer.

Когда ссылка установлена, можно вносить изменения в конфигурационный файл. Найдите в нем элемент <system. serviceModel> и добавьте в него следующий код.

<extensions> <bindingExtensions> <add name="pollingDuplexHttpBinding" type=

"System.ServiceModel.Configuration.

PollingDuplexHttpBindingCollectionElement,

System.ServiceModel.PollingDuplex, Version=3.0.0.0, Culture=neutral,

PublicKeyToken=31bf3856ad364e35"/> </bindingExtensions>

</extensions>

Этот код извлекает нужный класс из сборки System.ServiceModel. PollingDuplex. dll и применяет его для установки дополнения связывания.

Найдите раздел <bindings> и удалите из него элемент <customBinding>, вставив вместо него приведенный ниже элемент, в котором используется установленное выше дополнение связывания.

<pollingDuplexHttpBinding />

И наконец, найдите раздел <services> и замените в нем первый элемент <endpoint> следующим элементом.

<endpoint address="n binding="pollingDuplexHttpBinding"

contract="IAsyncTaskService"/>

Чтобы служба заработала, нужно создать интерфейс IAsyncTaskService, как описа­но в следующем разделе. Если присвоить интерфейсу службы другое имя, нужно будет изменить конфигурационную информацию.

Описанные выше операции конфигурируют службу на использование дуплексного связывания. Теперь можно добавлять код службы.

Интерфейсы

Для двусторонней коммуникации клиентского приложения со службой оно долж­но иметь необходимую информацию о службе, а служба — о клиентском приложении. Перед созданием кода нужно формализовать эту информацию, создав интерфейс. Для вызова службы клиентское приложение использует ее интерфейс (IAsyncTaskService). И наоборот, для вызова клиента служба использует его интерфейс (lAsyncTaskClient).

В данном примере интерфейс службы состоит из единственного метода SubmitTask (). Клиентское приложение вызывает этот метод для передачи запроса на сервер.

[ServiceContract(CallbackContract =

typeof(lAsyncTaskClient))]

public interface IAsyncTaskService

{

[OperationContract(IsOneWay = true)] void SubmitTask(TaskDescription task) ;

}

Важно отметить два существенных обстоятельства. Первое — то, что атрибут OperationContract метода SubmitTask() присваивает свойству IsOneWay значение true, которое делает метод односторонним. При вызове одностороннего метода клиент отключается после передачи запроса, не дожидаясь ответа. Это облегчает программи­рование кода на стороне сервера. Вместо создания нового потока или запуска таймера, метод SubmitTask () может выполняться от начала до конца, причем программисту не нужно беспокоиться о том, что клиент ждет.

Второе существенное обстоятельство связано с атрибутом ServiceContract, объ­явленным в интерфейсе. Он устанавливает свойство CallbackContract, чтобы опреде­лить, какой интерфейс будет использоваться клиентом. Клиентский интерфейс тоже содержит единственный односторонний метод, имеющий имя ReturnResult (). Сервер вызывает его для передачи результата клиенту по завершении операции.

[ServiceContract ]

public interface lAsyncTaskClient

{

[OperationContract(IsOneWay = true)] void ReturnResult(TaskResult result);

}

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

[DataContract()]

public class TaskDescription

{

[DataMember () ]

public string DataToProcess{ get; set; }

)

[DataContract ()]

public class TaskResult {

[DataMember () ]

public string ProcessedData { get; set; }

}

В этом простом примере каждый класс является оболочкой для единственной стро­ки, а обработка заключается всего лишь в инвертировании символов строки. Более сложная служба может генерировать растровую карту, просматривать архивированные документы, выполнять статистический анализ данных и т.д.

Код службы

Служба реализует интерфейс lAsyncTaskService и код для метода SubmitTaskO . В отличие от предыдущего примера, атрибута ServiceContract нет, потому что он уже представлен в интерфейсе.

Код метода SubmitTask (), как и код любого метода веб-службы, выполняет заданную операцию и готовит возвращаемое значение. В данном примере возвращаемое значе­ние передается явно путем вызова метода lAsyncTaskClient.ReturnResult ().

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class AsyncTask : lAsyncTaskService (

public void SubmitTask(TaskDescription taskDescription) {

// Задержка для имитации работы Thread.Sleep (TirneSpan.FromSeconds (15)) ;

// Инвертирование строки char[] data =

taskDescription.DataToProcess.ToCharArray(); Array.Reverse(data); // Подготовка ответа TaskResult result = new TaskResult (); result.ProcessedData = new string(data);

// Передача ответа клиенту

try {

IAsyncTaskClient client = OperationContext. Current. GetCallbackChannel <IAsyncTaskClient>(); client.ReturnResult(result);

}

catch {

// Контакта с клиентом нет, поэтому выполняется // очистка ресурсов перед завершением потока

Метод службы может вызвать метод client.ReturnResult () многократно для воз­вращения разных частей данных в разное время. Соединение с клиентом остается доступным, пока ссылка не будет очищена. Это происходит, когда метод завершается и переменная выходит из области видимости.

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии