Программирование >>  Программирование с использованием ajax 

1 ... 379 380 381 [ 382 ] 383 384 385 ... 396


Описание полученных результатов

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

Главное отличие в этом примере состоит в том, что клиенту не требовались никакие метаданные, поскольку у него был доступ к сборке контрактов. Вместо того чтобы генерировать прокси-класс из метаданных, клиент получал ссылку на интерфейс контракта службы посредством альтернативного метода. Еще одним моментом, на который нужно обратить внимание в этом примере, является использование сеанса для поддержания состояния в службе.

Контракт данных, использованный в этом примере, предназначался для простого класса по имени Person, имеющего свойство типа string с именем Name и свойство типа int с именем Mark. Атрибуты DataContractAttribute и DataMemberAttribute применяются без всякой настройки, да и в повторной итерации кода для этого контракта здесь нет никакой необходимости.

Контракт службы был определен путем применения к интерфейсу lAwardService атрибута ServiceContractAttribute. Для свойства SessionMode этого атрибута было установлено значение SessionMode.Required, поскольку данной службе требуется состояние:

[ServiceContract(SessionMode=SessionMode.Required)]

public interface lAwardService

Контракт первой операции - SetPassMark () - является именно тем, в котором устанавливается состояние и потому для свойства Isinitiating его атрибута Operation ContractAttribute устанавливается значение true. Эта операция ничего не возвращает и потому определяется как односторонняя операция путем установки IsOneWay в true:

[OperationContract(IsOneWay=true,Islnitiating=true)] void SetPassMark(int passMark);

Контракт другой операции - GetAwardedPeople () - не требует никакой настройки и использует определенный ранее контракт данных:

[OperationContract]

Person[] GetAwardedPeople(Person[] peopleToTest);

Напоминаем, что оба типа - Person и lAwardService - доступы и для службы, и для клиента. Служба реализует контракт lAwardService в типе по имени AwardService, который никакого примечательного кода не содержит. Единственное отличие между этим классом и классом службы, который демонстрировался ранее, состоит в том, что он обладает состоянием. Подобное является допустимым, поскольку для корреляции сообщений от клиента определяется сеанс.

Клиент выглядит интереснее в первую очередь из-за следующей строки кода:

lAwardService client = ChannelFactory<IAwardService>.CreateChannel( new WSHttpBindingO ,

new EndpointAddress( http: localhost:51425/AwardService.svc ));

Получается, что у клиентского прможения нет ни файла арр. conf ig для настройки коммуникаций со службой, ни прокси-класса, определяемого на основе метаданных для взаимодействия со службой. Вместо этого прокси-класс создается методом



ChannelFactory<T>. CreateChannel (). Этот метод создает прокси-класс, реализующий клиент lAwardService, хотя за кулисами этот генерируемый класс взаимодействует со службой точно так же, как и тот, что демонстрировался ранее и генерировался на основе метаданных.

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

Такое создание прокси-классов является чрезвычайно полезным приемом, которым можно пользоваться для быстрой генерации клиентского приложения в процессе работы.

Службы WCF с собственным хостом

Пока что в этой главе демонстрировались только WCF-службы, за хостинг которых отвечал Web-сервер. Такой подход удобен для обмена данными через Internet, но для обмена данными по локальной сети наиболее эффективным решением он не является. Во-первых, он требует наличия Web-сервера на том компьютере, который должен выступать в роли хоста службы. Во-вторых, архитектура создаваемых приложений может делать применение независимой WCF-службы нежелательным.

По этим причинам в некоторых случаях может быть выгоднее использовать WCF-службу с собственным хостом. WCF-службой с собственным хостом называется такая служба, которая существует в создаваемом самим разработчиком процессе, а не в процессе специально предназначенного для обеспечения хостинга приложения вроде Web-сервера. Это означает, что для хостинга службы можно использовать, например, консольное приложение или приложение Windows.

Для оснащения WCF-службы собственным хостом применяется класс System. ServiceModel. ServiceHost. Экземпляр этого класса создается с помощью либо типа службы, которую требуется снабдить хостом, либо экземпляра класса службы. Конфигурировать хост службы можно либо с помощью свойств и методов, либо (что разумнее) с применением конфигурационного файла. На самом деле процессы хостов вроде Web-серверов тоже используют для обеспечения своего хостинга экземпляр класса ServiceHost. Отличие состоит в том, что при снабжении службы собственным хостом взаимодействие с этим классом осуществляется напрямую. Однако синтаксис конфигурации, помещаемой в раздел <system. serviceModel> файла app. conf ig для приложения-хоста, выглядит абсолютно так же, как и в тех конфигурационных разделах, которые уже демонстрировались ранее в настоящей главе.

Предоставлять доступ к службе с собственным хостом можно через любой протокол, хотя обычно в приложениях такого типа все-таки применяется привязка к протоколу TCP или именованному каналу. Службы с доступом через протокол HTTP чаще всего функционируют внутри процессов Web-серверов, поскольку это обеспечивает их дополнительными функциональными возможностями, которые предлагают Web-серверы, вроде безопасности и т.п.

При желании снабдить хостом службу по имени MyService, например, можно было бы использовать для создания экземпляра класса ServiceHost такой код:

ServiceHost host = new ServiceHost(typeof(MyService));

A при желании снабдить хостом экземпляр MyService по имени myServiceObject, для создания экземпляра ServiceHost можно было бы применить следующий код:



MyService myServiceObject = new MyServiceO; ServiceHost host = new ServiceHost(myServiceObject);

Обратите внимание, что последний прием работает только при условии настройки службы таким образом, чтобы вызовы всегда направлялись одному и тому же экземпляру объекта, что требует применения к классу службы атрибута ServiceBehaviorAttribute и установки свойства InstanceContextMode этого атрибута в InstanceContextMode.Single.

После создания экземпляра ServiceHost можно переходить к настройке службы, ее конечных точек и привязки посредством свойств. Вместо свойств эту настройку можно выполнять и посредством файла . conf ig, в случае чего экземпляр ServiceHost будет конфигурироваться автоматически.

Для запуска хоста службы после настройки экземпляра ServiceHost применяется метод ServiceHost .Open (), а для останова - соответственно, метод ServiceHost .Close (). При первом запуске хоста привязанной к TCP службы может поступить предупреждающее сообщение от службы брандмауэра Windows, если таковая включена, поскольку эта служба по умолчанию блокирует ТСР-порт. В таком случае потребуется открыть ТСР-порт, чтобы служба начала ожидать подключения к данному порту.

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

Практическое занятие Службы WCF С СОбственным ХОСТОМ

1. Создайте новое приложение по имени Ch35Ex03 и сохраните его в каталоге

С:\BegVCSharp\Chapter35.

2. Добавьте в проект новую службу WCF AppControlService с помощью мастера добавления нового элемента (Add New Item Wizard).

3. Измените код в файле Windowl. xaml следующим образом:

<Window

xmlns= http: schemas.microsoft.com/winfх/2ОО6/xaml/presentation xmlns:x= http: schemas.microsoft.com/winfx/2006/xaml x:Class= Ch35Ex03.Windowl

Title= Solar Evolution Height= 450 Width= 430 Loaded= Window Loaded Closing= Window Closing >

<Grid Height= 400 Width= 400 HorizontalAlignment= Center VerticalAlignment= Center >

<Rectangle Fill= Black RadiusX= 20 RadiueY= 20 StrolceThickness= 10 > <Rectangle.Stroke>

<LinearGradientBrush EndPoint= 0.358,0.02 StartPoint= 0. 642,0. 98 > <GradientStop Color= #FF121A5D Offset= 0 /> <GradientStop Color= #FFBlB9FF Offset= l /> </LinearGradientBrush> </Rectangle.Stroke> </Rectangle>

<Ellipse Name= AnimatableEllipse Stroke= {x:Null} Height= 0 Width= 0 HorizontalAlignment= Center VerticalAlignment= Center > <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color= #FFFFFFFF Offset= 0 /> <GradientStop Color= #FFFFFFFF Offset= l /> </RadialGradientBrush> </Ellipse.Fill>



1 ... 379 380 381 [ 382 ] 383 384 385 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика