|
Программирование >> Программирование с использованием ajax
Описание полученных результатов в этом примере мы создали ряд контрактов в проекте библиотеки классов и использовали эту библиотеку классов и в 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>
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |