КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Режимы создания экземпляра (InstanceContextMode)
IV. III Только данные могут передаваться между службами и между клиентом и службой. Интерфейс между службой и клиентом может оперировать только данными. Программный код не должен передаваться между службой и клиентом. II. В приведенном ранее примере есть метод GetWeatherInfo, который возвращает структуру данных.
[DataContract] public class WeatherInfo { public WeatherInfo() { }
[DataMember] public double Temperature { get; set; }
[DataMember] public double Humidity { get; set; }
[DataMember] public double Pressure { get; set; }
public double GetTemperatureAsFahrenheit() { return Temperature * 9 / 5 + 32; } }
Сама структура помечена как DataContract (представляет собой часть контракта), некоторые поля этой структуры помечаются как DataMember, т.е. они входят в контракт. Следовательно, метод GetTemperatureAsFahrenheit не будет включен в контракт. После создания интерфейса необходимо создать класс, который его реализует.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)] public class WeatherService: IWeatherService { private string LastLocation;
public WeatherService() { Console.WriteLine("Создан экземпляр WeatherService"); }
public double GetTemperature(string location) { Console.WriteLine("Last location: {0}", LastLocation); return +15; }
public WeatherInfo GetWeatherInfo(string location) { Console.WriteLine("Last location: {0}", LastLocation); var res = new WeatherInfo() { Temperature = 15, Humidity = 50, Pressure = 710, }; return res; } }
Отделение конфигурации и средств хостинга от реализации. Реализация службы происходит за счет реализации методов, включенных в контракт. Этот принцип можно назвать принципом мобильности: служба может быть перенесена на другой узел, у нее могут быть изменены адреса доступа, но это никак не повлияет на саму службу.
Содержание файла App.config:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <compilation debug="true" /> </system.web> <!-- When deploying the service library project, the content of the config file must be added to the host's app.config file. System.Configuration does not support config files for libraries. --> <system.serviceModel> <services> <service name="WcfServiceLibrary1.WeatherService" behaviorConfiguration="WcfServiceLibrary1.Service1Behavior"> <host> <baseAddresses> <add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/WeatherService/" /> </baseAddresses> </host> <!-- Service Endpoints --> <!-- Unless fully qualified, address is relative to base address supplied above --> <endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IWeatherService"> <!-- Upon deployment, the following identity element should be removed or replaced to reflect the identity under which the deployed service runs. If removed, WCF will infer an appropriate identity automatically. --> <identity> <dns value="localhost"/> </identity> </endpoint> <!-- Metadata Endpoints --> <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> <!-- This endpoint does not use a secure binding and should be secured or removed before deployment --> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WcfServiceLibrary1.Service1Behavior"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="True"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
App.config – стандартный файл конфигурации, которым может быть оснащен проект решения Visual Studio. Файл содержит XML-конфигурацию прикладной программы и включается в состав компилируемого пакета как метаданные, читается системой.NET при загрузке программы. В случае с веб-службами создание ServiceHost обеспечивает чтение всех параметров этого хоста из.config файла.
Описание содержимого файла конфигурации:
Сервисно-ориентированная архитектура и ее реализация в.NET позволяет полностью отделить саму службу от привязки к точкам доступа. Запросы могут приниматься одновременно по нескольким протоколам – и по TCP (в бинарном формате), и по HTTP (в XML-формате), и по HTTPS. Разработка службы не зависит от этих протоколов.
Описание точки доступа:
<endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IWeatherService">
Точка доступа имеет адрес, по которому можно получить доступ. Пустой адрес значит, что будет использован базовый адрес.
Точка доступа имеет binding – вид привязки. Вид привязки определяет используемый транспортный протокол и формат данных. Например, HTTP + XML –> SOAP –> wsHttpBinding.
Точка доступа с адресом “mex” (от Metadata Exchange) использует вид привязки mexHttpBinding в сочетании с форматом передачи данных WSDL. Эта точка доступа со специальным контрактом IMetadataExchange позволяет, обратившись к службе с параметром mex, получить у веб-службы ее описание в формате WSDL. Сама служба сгенерирует по своему контракту WSDL-описание. То есть веб-служба позволяет клиенту после обращения за WSDL сгенерировать интерфейс обращения к службе для того языка, на котором работает клиент (это не обязательно будет C#).
Автономность – важный принцип создания веб-службы. Службы должны быть написаны в, исходя из предположения, что службы, от которых они зависят, могут быть недоступны, при этом служба все равно должна продолжать работать.
33.4 Пример веб-службы с применением WCF: клиент
1) создать ссылку на сервис (service reference): выбрать пункт «Добавить ссылку на службу…» контекстного меню обозревателя решений Visual Studio;
2) задать адрес WSDL схемы. После нажатия «Перейти» произойдет загрузка и служба WeatherService, у которой есть интерфейс с двумя методами (GetTemperature и GetWeatherInfo) будет найдена; 3) при нажатии кнопки «ОК» по схеме службы будет сгенерирован программный код клиента. Сама ссылка появляется в папке “Service references”; 4) Для обновления ссылки на сервис (перечитать WSDL-сервиса и заново сгенерировать программный код клиента) необходимо выбрать пункт «Обновить ссылку на сервис» в контекстном меню созданной ссылки. Сгенерированный класс WeatherServiceClient:
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public partial class WeatherServiceClient: System.ServiceModel.ClientBase<WcfServiceClient.ServiceReference1.WeatherService>, WcfServiceClient.ServiceReference1.WeatherService {
public WeatherServiceClient() { }
public WeatherServiceClient(string endpointConfigurationName): base(endpointConfigurationName) { }
public WeatherServiceClient(string endpointConfigurationName, string remoteAddress): base(endpointConfigurationName, remoteAddress) { }
public WeatherServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress): base(endpointConfigurationName, remoteAddress) { }
public WeatherServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress): base(binding, remoteAddress) { }
public double GetTemperature(string location) { return base.Channel.GetTemperature(location); }
public WcfServiceClient.ServiceReference1.WeatherInfo GetWeatherInfo(string location) { return base.Channel.GetWeatherInfo(location); } }
WeatherServiceClient – прокси на стороне клиента. Этот класс реализует интерфейс для работы с созданной веб-службой.
static void Main(string[] args) { var client = new WeatherServiceClient( new WSHttpBinding(SecurityMode.None, false), new EndpointAddress("net.tcp://localhost:5555/Design_Time_Addresses/WcfServiceLibrary1/WeatherService/")); var t = client.GetTemprature("Minsk"); var w = client.GetWeatherInfo("Minsk"); Console.WriteLine("Temperature: {0}, Humidity: {1}, Pressure: {2}", w.Temperature, w.Humidity, w.Pressure);
var sw = Stopwatch.StartNew(); var count = 1000; for (int i = 0; i < count; i++) var wh = client.GetWeatherInfo("Minsk"); Console.WriteLine("{0} calls of GetTemprature(\"Minsk\") took {1}", count, sw.Elapsed); Console.WriteLine("1 call of GetTemprature(\"Minsk\") takes {0} ms", (double)sw.ElapsedMilliseconds / count);
client.Close(); client = new WeatherServiceClient( new WSHttpBinding(SecurityMode.Message), new EndpointAddress("http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/WeatherService/")); t = client.GetTemprature("Minsk"); w = client.GetWeatherInfo("Minsk"); Console.WriteLine("Temperature: {0}, Humidity: {1}, Pressure: {2}", w.Temperature, w.Humidity, w.Pressure);
sw = Stopwatch.StartNew(); for (int i = 0; i < count; i++) var wh = client.GetWeatherInfo("Minsk"); Console.WriteLine("{0} calls of GetTemprature(\"Minsk\") took {1}", count, sw.Elapsed); Console.WriteLine("1 call of GetTemprature(\"Minsk\") takes {0} ms", (double)sw.ElapsedMilliseconds / count);
client.Close(); Console.ReadLine(); } Представленная выше программа служит для проверки производительности: в зависимости от конфигурации компьютера при расположении службы и клиента на одной машине она показывает, что 1000 вызовов GetTemperature занимает около 7-8 секунд, то есть один вызов метода занимает 0,007-0,008 секунды или 7-8 миллисекунд.
Результат работы программы показывает, что удаленные вызовы заметно замедляют выполнение. Поэтому очень важно грамотное проектирование распределенных программ и обдуманное использование удаленных вызовов.
33.5 Пример веб-службы с применением WCF: атрибут ServiceBehavior
Рассмотрим, от чего зависит, как создаются экземпляры объекта WeatherService и в каком режиме обслуживаются запросы. Управление этими параметрами осуществляется декларативно с помощью параметров. Атрибут ServiceBehavior описывает режим создания экземпляра (InstanceContextMode) и режим параллельного вызова (ConcurrencyMode) экземпляра.
Дата добавления: 2014-11-16; Просмотров: 426; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |