56
МАИ, каф 806, Сети ЭВМ WINDOWS COMMUNICATION FOUNDATION 1

МАИ, Сети ЭВМ, Лекция №7

Embed Size (px)

DESCRIPTION

Лекция рассказывает о базовых возможностях WCF по построению Web-Service и REST (json) интерфейсов. Рассматриваются базовые возможности Apache AXIS2.

Citation preview

Page 1: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

WINDOWS COMMUNICATION

FOUNDATION

1

Page 2: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

SOA

SOA (service oriented architecture) это стиль программирования, где программы

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

методов, которые объединены общим набором решаемых требований или целей.

Основные принципы SOA

Границы определены явно

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

адрес и контракт.

Сервисы являются автономными

работа одного сервиса не зависит от поведения другого

Сервисы описываются схемами и контрактами (а не классами)

сервисы должны быть кросс-платформенными, поэтому публикуются только описания

сервисов а не программный код

Совместимость сервисов базируется на policy

наборе правил, определяющих как обрабатывать сообщения

2

Page 3: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

REST (Representational State Transfer)

REST — это не стандарт и не спецификация, а архитектурный стиль, выстроенный на

существующих, хорошо известных и контролируемых консорциумом W3C стандартах, таких,

как HTTP, URI (Uniform Resource Identifier), XML и RDF (Resource Description Format).

В REST-сервисах акцент сделан на доступ к ресурсам, а не на исполнение удаленных

сервисов; в этом их кардинальное отличие от SOAP-сервисов. Если SOAP-клиенты

запрашивают выполнение действия на сервере, то REST-клиенты попросту требуют сам

ресурс

Наипростейший REST-сервис можно реализовать за несколько минут — статичный XML-

файл, возвращаемый Web-сервисом, это технически и есть REST-сервис, ведь XML-данные

запрашивались через HTTP. Это вряд ли может стать оптимальным способом построения

вашей сервисной инфраструктуры, но для статичных или редко меняющихся ресурсов такая

возможность весьма привлекательна.

3

Page 4: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Популярность различных подходов к построению API

4

Page 5: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

структура сервиса

5

Page 6: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

технологии/xml

XML – это иерархический, текстовый язык

разметки, предоставляющий стандартный способ

для представления метаданных в понятном для

человека и компьютера виде.

Для ссылок на другие документы в XML

используются URI

Namespace используется для уникальной

идентификации частей XML документа

6

<?xml version=‘1.0’ encoding=‘utf-8’?>

<!-- A collection of Media Items -->

<Collection xmlns="http://example.com/schemas/mediacollection">

<Owner>Janine Labrune</Owner>

<Name>Janine’s Media Collection</Name>

<Item Media_Type="book">

<Title>The Joy of Rutabagas</Title>

<Author>

<FirstName>Karl</FirstName>

<LastName>Jablonski</LastName>

</Author>

</Item>

<Item Media_Type="video">

<Title>Growing Rutabagas as Pets</Title>

<Length>35</Length>

<Author>

<FirstName>Maria</FirstName>

<LastName>Anders</LastName>

</Author>

</Item>

</Collection>

<p:payload xmlns:p="http://example.com/payload">

<p:owner name="tim" />

<p:text>Payload text</p:text>

</p:payload>

Page 7: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

технологии/xml schemas

Схемы – это XML документы, которые описывают структуру типов данных и их свойства.

Обычно используется XSD (schema definition language).

7

<xsd:schema xmlns="http://example.com/schemas/mediacollection"

targetNamespace="http://example.com/schemas/mediacollection"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

elementFormDefault="qualified">

<xsd:element name="Collection">

<xsd:complexType>

<xsd:sequence>

<xsd:element name="Owner" minOccurs="1" type="xsd:string" />

<xsd:element name="Name" minOccurs="1" type="xsd:string" />

<xsd:element name="Item" minOccurs="0" maxOccurs="unbounded">

<xsd:complexType>

<xsd:sequence>

<xsd:element name="Title" minOccurs="1" type="xsd:string" />

<xsd:element name="Length" minOccurs="0" type="xsd:int" />

<xsd:element name="Author" minOccurs="0" maxOccurs="1">

<xsd:complexType>

<xsd:sequence>

<xsd:element name="FirstName" minOccurs="0"

maxOccurs="1" type="xsd:string" />

<xsd:element name="LastName" minOccurs="0" maxOccurs="1"

type="xsd:string" />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:sequence>

<xsd:attribute name="Media_Type" type="xsd:string" />

</xsd:complexType>

</xsd:element>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

Page 8: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ8

Windows Communication Foundation

технологии/wsdl [1/2]

WSDL – язык описания веб-сервиса.

WSDL состоит из двух частей:

Абстрактной, описывающей структуру данных и методов веб-сервиса.

Конкретной, описывающей, как данный веб-сервис может быть вызван.

Элементы WSDL

Types – описывает типы данных, передаваемые и получаемые веб-сервисом.

Message – описывает сообщения, передаваемые по сети при вызове веб-сервисов.

PortType – абстрактное описание веб-сервиса. Состоит из описания набора операций, которые могут иметь как входные так и выходные сообщения.

Binding – конкретное описание PortType, с указанием протокола, по которому можно вызвать данный сервис.

Service – конкретное описание веб-сервиса, которое указывает по какому адресу может быть вызван тот или иной Binding.

Page 9: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ9

Windows Communication Foundation

технологии/wsdl [2/2]

<?xml version="1.0" encoding="utf-8"?>

<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

<wsdl:types>

<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">

<s:element name="HelloWorld"> …

<s:element name="HelloWorldResponse">

<s:complexType>

<s:sequence>

<s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string" />

</s:sequence>

</s:complexType>

</s:element>

</s:schema>

</wsdl:types>

<wsdl:message name="HelloWorldSoapIn"> …

<wsdl:message name="HelloWorldSoapOut">

<wsdl:part name="parameters" element="tns:HelloWorldResponse" />

</wsdl:message>

<wsdl:portType name="ServiceSoap">

<wsdl:operation name="HelloWorld">

<wsdl:input message="tns:HelloWorldSoapIn" />

<wsdl:output message="tns:HelloWorldSoapOut" />

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="ServiceSoap" type="tns:ServiceSoap">

<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />

<wsdl:operation name="HelloWorld">

<soap:operation soapAction="http://tempuri.org/HelloWorld" style="document" />

<wsdl:input>

<soap:body use="literal" />

</wsdl:input>

<wsdl:output>

<soap:body use="literal" />

</wsdl:output>

</wsdl:operation>

</wsdl:binding>

<wsdl:binding name="ServiceSoap12" type="tns:ServiceSoap"> …

<wsdl:service name="Service">

<wsdl:port name="ServiceSoap" binding="tns:ServiceSoap">

<soap:address location="http://localhost:1327/Lab1/Service.asmx" />

</wsdl:port>

<wsdl:port name="ServiceSoap12" binding="tns:ServiceSoap12"> …

</wsdl:service>

</wsdl:definitions>

Page 10: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

технологии/ws-inspection

Способ описания сервисов, предоставляемых сайтом. Представляет собой набор указателей

на описание сервисов (http://msdn.microsoft.com/en-us/library/ms951237.aspx ).

10

<?xml version="1.0"?>

<inspection xmlns="http://schemas.xmlsoap.org/ws/2001/10/inspection/"

xmlns:wsiluddi="http://schemas.xmlsoap.org/ws/2001/10/inspection/uddi/">

<service>

<abstract>A stock quote service with two descriptions</abstract>

<description referencedNamespace="http://schemas.xmlsoap.org/wsdl/"

location="http://example.com/stockquote.wsdl"/>

<description referencedNamespace="urn:uddi-org:api">

<wsiluddi:serviceDescription location="http://www.example.com/uddi/inquiryapi">

<wsiluddi:serviceKey>4FA28580-5C39-11D5-9FCF-BB3200333F79</wsiluddi:serviceKey>

</wsiluddi:serviceDescription>

</description>

</service>

<service>

<description referencedNamespace="http://schemas.xmlsoap.org/wsdl/"

location="ftp://anotherexample.com/tools/calculator.wsdl"/>

</service>

<link referencedNamespace="http://schemas.xmlsoap.org/ws/2001/10/inspection/"

location="http://example.com/moreservices.wsil"/>

</inspection>

Page 11: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ11

Windows Communication Foundation

технологии/soap

Simple Object Access Protocol – протокол передачи данных на базе XML. Данные передаются с помощью протокола HTTP.

Структура SOAP сообщения соответствует WSDL описанию веб-сервиса.

Пример запроса

<?xml version="1.0" encoding="utf-8" ?>

<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<soap:Body>

<HelloWorld xmlns="http://tempuri.org/"></HelloWorld>

</soap:Body>

</soap:Envelope>

Пример ответа

<?xml version="1.0" encoding="utf-8" ?>

<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<soap:Body>

<HelloWorldResponse xmlns="http://tempuri.org/">

<HelloWorldResult>Hello World! </HelloWorldResult>

</HelloWorldResponse>

</soap:Body>

</soap:Envelope>

Page 12: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

технологии/ws-addressing

WS-Addressing заменила собой спецификацию WS-Routing. WS-Addressing включает в себя

механизм для идентификации сообщений (MessageID), определения получателя (To) и

объекта, которому должен быть послан ответ (ReplyTo).

Этот механизм встроен в заголовок SOAP и удлиняет входящие, исходящие сообщения и

сообщения об ошибках внутри элемента, определяющего тип порта WSDL с помощью

атрибута Action.

12

Page 13: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

технологии/ws-addressing

13

<soapenv:Envelope xmlns:soapenv='http://www.w3.org/2003/05/soap-envelope'>

<soapenv:Header xmlns:wsa='http://www.w3.org/2005/08/addressing'>

<wsa:To>http://localhost:9090/axis2/services/order_service</wsa:To>

<wsa:Action>http://wso2.org/wsf/c/addr/order</wsa:Action>

<wsa:ReplyTo>

<wsa:Address>http://localhost:9090/axis2/services/billing_service</wsa:Address>

</wsa:ReplyTo>

<wsa:FaultTo>

<wsa:Address>http://localhost:9090/axis2/services/reorder_service</wsa:Address>

</wsa:FaultTo>

<wsa:MessageID>a4dfb94a-593b-1dc1-36d2-000000000000</wsa:MessageID>

</soapenv:Header>

<soapenv:Body>

<ns1:order xmlns:ns1='http://wso2.org/wsf/c/addr/sample'>

<item>paper</item>

<quantity>100</quantity>

</ns1:order>

</soapenv:Body>

</soapenv:Envelope>

Page 14: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

паттерны обмена сообщениями/запрос-ответ

Самый распространненый паттерн.

Клиент запрашивает информацию отправкой запроса на

сервер и ожидает ответное сообщений от сервера.

Клиент ждет ответа не более чем заранее определенное

время (timeout)

В случае возникновения исключения посылается сообщение с

описанием ошибки.

WCF поддерживает описания удаленных интерфейсов, путем

применения атрибутов

[ServiceContract] к .NET интерфейсам

[OperationContract] к методам интерфейса

14

Page 15: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

паттерны обмена сообщениями/one-way

Сообщения посылаются от клиента к серверу в одном

направлении.

Сервер просто обрабатывает сообщения и не отправляет

клиенту ответа или уведомления об обработке сообщения.

Данный паттерн позволяет работать ассинхронно.

С помощью данного паттерна можно применять

промежуточное по для отправки сообщений, такое как

MSMQ.

15

Page 16: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

паттерны обмена сообщениями/duplex

Данный паттерн позволяет серверу посылать

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

выполнения обработки основного запроса.

Фактически клиент так же выступает в роли сервера,

для выполнения call-back операций.

В .NET есть возможность указать тип Call-Back

интерфейса на уровне [Service Contract]

В WCF есть специальные типы binding, которые

поддерживают call-back соединения.

16

Page 17: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

паттерны обмена сообщениями/streaming

Данный паттерн применяется в случае если необходимо

передать большой объем информации от сервера к

клиенту (или наоборот).

Информация считывается из файла или базы данных по

кускам и передается в сеть.

Отправитель сам определяет когда закончить передачу

данных (какой блок является финальным).

17

Page 18: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

работа с сообщениями

Message RoutingНачиная с WCF 4.0 есть поддержка перенаправления сообщений, базируясь

на их содержании, с помощью специальных классов, переопределяющих

интерфейсы из System.ServiceModel.Routing

Protocol BindingВ WCF 4.0 есть средства приведения протокола (чтением данных из

протокола источника и записью в протокол получатель).

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

сервисом должно обрабатываться (Xpath, по телу сообщения)

Backup Endpoint

Multicast BehaviourРеализуется с помощью фильтров. Одно сообщение посылается сразу всем

сервисам, с подходдящим фильтром.

Discovery (WS-Discovery)

Intercepting FiltersПозволяет встраивать логику перед или после обработки основного вызова

Context Objects

18

Page 19: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ19

Windows Communication Foundation

контракты

Контракт – определяет функциональность,

предоставляемую службой и функциональность,

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

Типы контрактов

Контракты данных – определяет данные,

принимаемые и возвращаемые службой.

Контракты службы – используется для

определения интерфейса службы;

Контракты сообщений – в случае если требуется

описывает поведение сообщений, передаваемых

при взаимодействии со службой.

Page 20: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ20

Windows Communication Foundation

контракты служб [1/2]

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

1. [ServiceContract()]

2. public interface IMyService

3. {

4. [OperationContract]

5. OutputObject doAction(InputObject parameter);

6. }

Свойства ServiceContract

ConfigurationName – имя конфигурации службы в конфигурационном файле

CallbackContract – используется для дуплексного обмена (см. далее)

Name – определяет имя элемента portType

Namespace – определяет пространство имен для portType

SessionMode – управление сессиями

ProtectionLevel – управление защитой коммуникаций

Page 21: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ21

Windows Communication Foundation

контракты служб [2/2]

Свойства OperationContract

Action – Используется для установки соответствия имен операций и SOAP

сообщений

ReplyAction – то же самое что и Action но для сообщений-ответов

AsyncPattern – используется для асинхронного обмена (BeginAsync,

EndAsync)

IsInitiating – Операция инициирующая сеанс

IsTerminating – Операция завершающая сеанс

IsOneWay – Клиент не должден ждать результата от сервиса

Name – Имя операции (по умолчанию равно имени метода)

ProtectionLevel - управление защитой коммуникаций

Page 22: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ22

Windows Communication Foundation

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

Пример

1. [DataContract]

2. public class OutputObject

3. {

4. string message;

5. [DataMember]

6. public string Message

7. {

8. get { return message; }

9. set { message = value; }

10. }

11. }

Свойства DataMember

Name – служит для изменения имени атрибута

Order – определяет порядок сериализации атрибутов

IsRequired – элемент обязателен для сериализации (по умолчанию не обязательны)

EmitDefaultValue - необходимость передачи значения по умолчанию для поля

Page 23: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

контракты данных/пример

[DataContract(

Name="PriceCalculationRequest", Namespace=

"http://schemas.datacontract.org/2004/07/

MyScheme")]

public class PriceReq

{

[DataMember(Name="PickupDate",Order=1,

IsRequired=true )]

private DateTime FromDate { get; set; }

[DataMember(Name = "ReturnDate", Order = 3)]

public DateTime ToDate{ get; set; }

[DataMember( Order = 2)]

public string PickupLocation { get; set; }

[DataMember(Order = 4)]

public string ReturnLocation { get; set; }

public string CarType { get; set; }

}

<xs:complexType name="PriceCalculationRequest" >

<xs:sequence >

<xs:element minOccurs="0" name="PickupDate"

type="xs:dateTime" / >

<xs:element minOccurs="0" name="PickupLocation"

nillable="true" type="xs:string" / >

<xs:element minOccurs="0" name="ReturnDate"

type="xs:dateTime" / >

<xs:element minOccurs="0" name="ReturnLocation"

nillable="true" type="xs:string" / >

</xs:sequence>

</xs:complexType>

23

Page 24: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

контракты данных/наследование

Описание на уровне контракта данных, то какие объекты могут передаваться:

[DataContract]

[KnownType(typeof(PriceCalculationResponseDetailed))]

public class PriceCalculationResponse{

[DataMember]

public double Price { get; set; } }

Описание на уровне метода

[OperationContract]

[ServiceKnownType(typeof(PriceCalculationResponseDetailed))]

PriceCalculationResponse CalculatePrice(PriceCalculationRequest request);

Описание на уровне сервиса

[OperationContract]

[ServiceKnownType(typeof(PriceCalculationResponseDetailed))]

PriceCalculationResponse CalculatePrice(PriceCalculationRequest request);

Динамическое описание

[DataContract]

[KnownType("GetTypes")]

public class PriceCalculationResponse {

static Type[] GetTypes() { Type[] t = { typeof(PriceCalculationResponseDetailed) }; return t;

}

}

24

Page 25: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

контракты данных/версии

При модификации программы контракты данных могут менять свою структуру. Для того что

бы корректно отрабатывать данную ситуацию необходимо на уровне базового объекта

определить возможность расширения:

[DataContract]

public class PriceCalculationResponse :IExtensibleDataObject

{

public ExtensionDataObject ExtensionData { get; set; }

[DataMember]

public int Flag { get; set; }

[DataMember]

public double Price { get; set; }

[DataMember]

public string Currency { get; set; }

}

25

Page 26: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ26

Windows Communication Foundation

контракты сообщений

Используется для контроля над SOAP сообщениями.

Пример

1. [MessageContract]

2. public class MyRequestMessage

3. {

4. [MessageHeader]

5. public int count;

6. [MessageBodyMember(Order = 0)]

7. public String person;

8. }

9. [ServiceContract]

10. public interface IMyRequestHandler

11. {

12. [OperationContract]

13. bool ProcessRequest(MyRequestMessage msg);

14. }

Page 27: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ27

Windows Communication Foundation

пример/cборка с описанием данных и сервиса [1/2]

1. using System;

2. using System.Collections.Generic;

3. using System.ServiceModel;

4. using System.Runtime.Serialization;

5. namespace WCFServiceExample

6. {

7. [DataContract]

8. public class InputObject

9. {

10. string firstName;

11. string lastName;

12. [DataMember]

13. public string FirstName

14. {

15. get { return firstName; }

16. set { firstName = value; }

17. }

18. [DataMember]

19. public string LastName

20. {

21. get { return lastName; }

22. set { lastName = value; }

23. }

24. }

25. [DataContract]

26. public class OutputObject

27. {

28. string message;

29. [DataMember]

30. public string Message

31. {

32. get { return message; }

33. set { message = value; }

34. }

35. }

36. }

Page 28: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ28

Windows Communication Foundation

пример/cборка с описанием данных и сервиса [2/2]

1. using System;

2. using System.Collections.Generic;

3. using System.Text;

4. using System.ServiceModel;

5. using System.Runtime.Serialization;

6. namespace WCFServiceExample

7. {

8. [ServiceContract()]

9. public interface IMyService

10. {

11. [OperationContract]

12. OutputObject doAction(InputObject parameter);

13. }

14. public class MyServiceImpl : IMyService

15. {

16. #region IMyService Members

17. public OutputObject doAction(InputObject parameter)

18. {

19. OutputObject obj = new OutputObject();

20. obj.Message = String.Format("Hello {0} {1}!", parameter.FirstName, parameter.LastName);

21. return obj;

22. }

23. #endregion

24. }

25. }

Page 29: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ29

Windows Communication Foundation

пример/хост

1. using System;

2. using System.Collections.Generic;

3. using System.Text;

4. using WCFServiceExample;

5. using System.ServiceModel;

6. using System.ServiceModel.Channels;

7. using System.Net;

8. namespace WCFServiceHost

9. {

10. class Program

11. {

12. static void Main(string[] args) {

13. ServiceHost host = ConfigureFromFile();

14. host.Open();

15. Console.WriteLine("Service started"); Console.ReadLine();

16. host.Close();

17. }

18. static ServiceHost ConfigureInline() {

19. Uri base_address = new Uri("http://localhost:8080/MyService");

20. ServiceHost host = new ServiceHost(typeof(MyServiceImpl), base_address);

21. host.AddServiceEndpoint(typeof(IMyService), new WSHttpBinding(), "");

22. return host;

23. }

24. static ServiceHost ConfigureFromFile() {

25. ServiceHost host = new ServiceHost(typeof(MyServiceImpl));

26. return host;

27. }

28. }

29. }

Page 30: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ30

Windows Communication Foundation

пример/конфигурация (App.Config)

1. <?xml version="1.0" encoding="utf-8" ?>

2. <configuration>

3. <system.serviceModel>

4. <services>

5. <service name ="WCFServiceExample.MyServiceImpl" behaviorConfiguration="MyServiceBehavior">

6. <endpoint contract="WCFServiceExample.IMyService" binding="wsHttpBinding"/>

7. <endpoint contract="IMetadataExchange" binding="wsHttpBinding" address="mex"/>

8. <host>

9. <baseAddresses>

10. <add baseAddress="http://localhost:8080/MyService"/>

11. </baseAddresses>

12. </host>

13. </service>

14. </services>

15. <behaviors>

16. <serviceBehaviors>

17. <behavior name="MyServiceBehavior" >

18. <serviceMetadata httpGetEnabled="true" />

19. </behavior>

20. </serviceBehaviors>

21. </behaviors>

22. </system.serviceModel>

23. </configuration>

Page 31: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ31

Windows Communication Foundation

пример/клиент

Создаем проект

Создаем ссылку на службу (Add Web-reference). При этом добавляются сборки System.Runtime.Serialization и System.ServiceModel

Пишем код

1. using System;

2. using System.Collections.Generic;

3. using System.Text;

4. using WCFServiceExample;

5. namespace WCFClient

6. {

7. class Program

8. {

9. static void Main(string[] args)

10. {

11. Console.WriteLine("Connecting to server ..");

12. InputObject inp = new InputObject();

13. inp.LastName = "Ivanov";

14. inp.FirstName = "Ivan";

15. MyServiceClient srv = new MyServiceClient();

16. OutputObject otp = srv.doAction(inp);

17. Console.WriteLine(otp.Message);

18. Console.ReadLine();

19. }

20. }

21. }

Page 32: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ32

Windows Communication Foundation

пример/клиентская конфигурация

1. <?xml version="1.0" encoding="utf-8" ?>

2. <configuration>

3. <system.serviceModel>

4. <bindings>

5. <wsHttpBinding>

6. <binding name="WSHttpBinding_IMyService" closeTimeout="00:01:00"

7. openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"

8. bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"

9. maxBufferPoolSize="524288" maxReceivedMessageSize="65536"

10. messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"

11. allowCookies="false">

12. </binding>

13. </wsHttpBinding>

14. </bindings>

15. <client>

16. <endpoint address="http://localhost:8080/MyService" binding="wsHttpBinding"

17. bindingConfiguration="WSHttpBinding_IMyService" contract="IMyService"

18. name="WSHttpBinding_IMyService">

19. </endpoint>

20. </client>

21. </system.serviceModel>

22. </configuration>

Page 33: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ33

Windows Communication Foundation

binding

Binding определяет как служба будет взаимодействовать с

клиентами. А именно:

Адрес;

Транспортный протокол;

Требования к безопасности;

Формат кодирования;

Требования транзакций;

Определяются на уровне создания хоста сервиса;

Page 34: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ34

Windows Communication Foundation

ServiceBehavior

ServiceBehavior определяется на уровне класса, реализующего ServiceContract (наследующего интерфейс). Описывает доп. функциональность, для службы.

Пример1. [ServiceBehavior]

2. public class MyServiceImpl : IMyService

3. {

4. public OutputObject doAction(InputObject parameter)

5. { return new OutputObject();}

6. }

Значения

TransactionAutoCompleteOnSessionClose – аналог [AutoComplete]

TransactionIsolationLevel – уровень изоляции транзакций

ReleaseServiceInstanceOnTransactionComplete – Позволяет повторное использование экземпляра объекта

AutomaticSessionShutdown – Разрывает сеанс при окончании вызова

InstanceContextMode – Аналог SingleCall/Singleton в Remoting

ConcurrencyMode – Управление множественным доступом к службе из разных клиентов (single/multi)

UseSynchronizationContext – Для внутренних служб WinForms, что бы создавать службу в потоке, в котором она инициируется

IncludeExceptionDetailInDaults – Включать в Exception развернутое описание ошибки

MaxItemsInObjectGraph – ограничение числа передаваемых объектов

AddressFilterMode: Управление фильром сообщений: Any , Exact , and Prefix ..

IgnoreExtensionDataObject: Если установленно в true то расширения не передаются..

Page 35: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

metadata publishing

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

ServiceMetadataBehavior serviceMetadata =

host.Description.Behaviors.Find < ServiceMetadataBehavior > ();

if (serviceMetadata == null)

{

serviceMetadata = new ServiceMetadataBehavior();

host.Description.Behaviors.Add(serviceMetadata);

}

serviceMetadata.HttpGetEnabled = true;

BasicHttpBinding binding = new BasicHttpBinding();

host.AddServiceEndpoint(typeof(IMyService),

Binding,"http://localhost:8080/MyService");

35

Page 36: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ36

Windows Communication Foundation

OperationBehavior

Применяется к методам класса, реализующего интерфейс с ServiceContract

Значения

AutoDisposeParameters – если стоит true – то за очистку параметров отвечает сервер,

иначе – клиент.

Impersonation – позволяет идентифицировать вызывающего;

ReleaseInstanceMode – определяет режим освобождения экземпляра (на уровне

операции);

TransactionScopeRequired – требуется ли транзакция или нет;

TransactionAutoComplete – должна ли транзакция завершаться автоматически или нет;

Page 37: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

OperationBehavior/пример

using System;

using Wrox.CarRentalService.Contracts;

namespace Wrox.CarRentalService.Implementations.Europe

{

public class CarRentalService : ICarRentalService

{

[OperationBehavior(

AutoDisposeParameters = true,

Impersonation = ImpersonationOption.NotAllowed,

ReleaseInstanceMode = ReleaseInstanceMode.None,

TransactionAutoComplete = true,

TransactionScopeRequired = false)]

double CalculatePrice(DateTime pickupDate, DateTime returnDate,string pickupLocation, string

vehiclePreference)

{

// method code here

}

}

}

37

Page 38: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

endpoint behaviour/пример

CarRentalServiceClient client = new

CarRentalServiceClient();

try

{

client.ClientCredentials.ClientCertificate.SetCerti

ficate(

StoreLocation.CurrentUser,

StoreName.My,

X509FindType.FindBySubjectDistinguishedName,

"CN=client_cert");

// other code

client.Close();

}

catch (Exception ex)

{

client.Abort();

throw;

}

ServiceHost host = new

ServiceHost(typeof(CarRentalService));

try

{

BasicHttpBinding binding = new BasicHttpBinding();

ServiceEndpoint serviceEndpoint =

host.AddServiceEndpoint(typeof(ICarRentalService),

binding,

"http://localhost:8080/CarRentalService");

ServiceCredentials credentials = new

ServiceCredentials();

credentials.ServiceCertificate.SetCertificate(

StoreLocation.CurrentUser,

StoreName.My,

X509FindType.FindBySubjectDistinguishedName,

"CN=service_cert");

host.Open();

// other code here ...

host.Close();

38

Page 39: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

стандартные binding

39

Page 40: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

клиенты

40

Page 41: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ41

Windows Communication Foundation

клиенты

Клиентскому приложению для получения доступа к службе нужен прокси. Его можно создать:

Visual Studio – Add Service Reference

Инструмент svcutil.exe

Класс ChannelFactory<TChannel>

Пример

1. static OutputObject UseChannelFactory(InputObject inp)

2. {

3. WSHttpBinding binding = new WSHttpBinding();

4. EndpointAddress address = new EndpointAddress("http://localhost:8080/MyService");

5. ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(binding, address);

6. try

7. {

8. IMyService service = factory.CreateChannel();

9. return service.doAction(inp);

10. }

11. finally

12. {

13. factory.Close();

14. }

15. }

Page 42: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ42

Windows Communication Foundation

дуплексная коммуникация

При дуплексной коммуникации служба может вызывать клиента;

Канал должен быть дуплексным;

На стороне клиента описывается контракт, который прописывается на сервере в свойстве

CallbackContract;

1. [ServiceContract(CallbackContract=typeof(ICalculatorDuplexCallback))]

2. public interface ICalculatorDuplex{

3. [OperationContract(IsOneWay = true)]

4. void AddTo(double n);

5. }

Клиент

1. public interface ICalculatorDuplexCallback{

2. [OperationContract(IsOneWay = true)]

3. void Equals(double result);

4. }

Вызов клиента на сервере

callback =

OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();

Page 43: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ43

Windows Communication Foundation

использование HTTPS и NTLM авторизации

1. <?xml version="1.0" encoding="utf-8" ?>

2. <configuration>

3. <system.serviceModel>

4. <bindings>

5. <basicHttpBinding>

6. <binding name="ClientServiceSoap" closeTimeout="00:01:00" openTimeout="00:01:00"

7. receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"

8. bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"

9. maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"

10. messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"

11. useDefaultWebProxy="true">

12. <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"

13. maxBytesPerRead="4096" maxNameTableCharCount="16384" />

14. <security mode="Transport">

15. <transport clientCredentialType="Ntlm" realm="tfs.sitels.ru" />

16. <message clientCredentialType="UserName" algorithmSuite="Default" />

17. </security>

18. </binding>

19. </basicHttpBinding>

20. </bindings>

21. <client>

22. <endpoint address="https://tfs.sitels.ru:8081/WorkItemTracking/v1.0/ClientService.asmx"

23. binding="basicHttpBinding"

24. bindingConfiguration="ClientServiceSoap"

25. contract="TFSService.ClientServiceSoap" name="ClientServiceSoap" />

26. </client>

27. </system.serviceModel>

28. </configuration>

Page 44: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ44

Windows Communication Foundation

потоковые данные

Устанавливаем transferMode="Streamed" в Binding (клиента и сервера).

Устанавливаем <httpRuntime maxRequestLength="65536"/> (сервер)

Описываем MessageContract (должен быть тип данных с потоком

[MessageContract]

public class FileUploadMessage

{

[MessageHeader(MustUnderstand = true)]

public DataContracts.DnvsDnvxSession DnvxSession

[MessageHeader(MustUnderstand = true)]

public DataContracts.EApprovalContext Context

[MessageHeader(MustUnderstand = true)]

public DataContracts.FileMetaData FileMetaData

[MessageBodyMember(Order = 1)]

public System.IO.Stream FileByteStream

}

Описываем серверный контракт

[OperationContract(Action = "UploadFile", IsOneWay = true)]

void UploadFile(ServiceContracts.FileUploadMessage request);

Реализуем сервер

public void UploadFile(FileUploadMessage request)

{

Stream sourceStream = request.FileByteStream;

Page 45: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

instancecontectmode/PerCall

// Per Call

[ServiceBehavior(

InstanceContextMode = InstanceContextMode.PerCall)]

public class CarRentalService: ICarRentalService

{

//Singleton

[ServiceBehavior(InstanceContextMode =

InstanceContextMode.Single,

ConcurrencyMode = ConcurrencyMode. Multiple )]

public class CarRentalService: ICarRentalService

{

// Per session

[ServiceBehavior(InstanceContextMode =

InstanceContextMode.PerSession)]

public class CarRentalService: ICarRentalService

{

PerCall

При каждом новом вызове сервера создается новый

экземпляр объекта на сервере.

Очень удобно для масштабирования.

Накладные расходы на создание объекта.

Singleton

Используется один экземпляр всегда.

Необходимо установить ConcurrencyMode.Multiple

PerSession

Каждый клиент взаимодействует всегда с одним и

тем же сервером.

Взаимодействие обрывается по таймауту или по

прерывании сессии клиентом (вызов метода Close).

45

Page 46: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

serviceThrottling Behavior

< serviceBehaviors >

< behavior name="throttlingBehavior" >

< serviceThrottling

maxConcurrentCalls ="5"

maxConcurrentSessions="2"

maxConcurrentInstances="3" / >

< /behavior >

< /serviceBehaviors >

Включение счетчиков производительности

< system.serviceModel >

< diagnostics performanceCounters="All"/ >

< /system.serviceModel >

Позволяет управлять нагрузкой на сервер

Ограничивает максимальное число параллельно

выполняемых процессов

Максимальное число параллельно

поддерживаемых сессий

Максимальное число одновременно загруженных

в память объектов сервера

46

Page 47: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Windows Communication Foundation

ConcurrencyMode

Устанавливается ServiceBehavior

По умолчанию, ConcurrencyMode.Single

У одному объекту может обращаться только один поток (клиент)

Нет проблем с разделяемым доступом к ресурсам

ConcurrencyMode.Multiple

Любое количество потоков может обращаться к объекту

Необходимо решать проблемы с разделяемым доступом

Имеет значение если вы разрабатываете многопоточный клиент с методом доступа

PerSession или Singleton.

В случае PerCall – на каждый запрос и так создается новый серверный объект.

47

Page 48: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ48

Windows Communication Foundation

итого

Комбинирует функциональность Web-Service, .NET Remoting, MSMQ и Enterprise Services;

Включает средства для обеспечения:

Настраиваемый хостинг компонентов и служб;

Декларативное поведение;

Различные коммуникационные каналы (HTTP, TXP, ...);

Инфраструктура безопасности;

Расширяемость (сбоственные каналы, форматировщики и прокси);

Поддержка предшествующих технологий (например можно сделать WCF сервис,

взаимодействующий с Web Service)

Page 49: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

REST

System.ServiceModel.Web

Используется расширение WebGet и WebInvoke дл OperationContract и webHttpBinding

[ServiceContract()]

public interface ICarRentalService

{

[OperationContract]

[WebGet(UriTemplate = "/CarPool")]

CarPool GetAllCars();

[OperationContract]

[WebGet(UriTemplate = "/CarPool/{carName}?format=xml",ResponseFormat = WebMessageFormat.Xml)]

Car GetCarXML(string carName);

[OperationContract]

[WebGet(UriTemplate = "/CarPool/{carName}?format=json",ResponseFormat = WebMessageFormat.Json)]

Car GetCarJSON(string carName);

[OperationContract]

[WebInvoke(UriTemplate = "CarPool/{carName}", Method = "PUT")]

Car AddCar(string carName, Car car);

[OperationContract]

[WebInvoke(UriTemplate = "/CarPool/{carName}", Method = "DELETE")]

void DeleteCar(string carName);

}

49

Page 50: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

Что почитать?

PROFESSIONAL

WCF 4

WINDOWS

COMMUNICATION

FOUNDATION WITH .NET 4

Pablo Cibraro Kurt Claeys Fabio

Cozzolino Johann Grabner

50

Page 51: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

AXIS2

Web-services & java

51

Page 52: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

AXIS2

Класс ServiceClient – простой прием и отправка XML сообщений

ServiceClient имеет следующий набор API

sendRobust – просто отправка XML без ожидания ответа, но с получением Exception в

случае ошибуи.

FireAndForget – просто отправка XML без ожидания ответа или исключения

SendRecieve – отправка запроса и получение ответа

SendReceiveNonBlocking – То же что и SendReceive но с получением ответа через

CallBack объект.

Трансортный уровень

HTTP/HTTPS

TCP (только совместно с WS-Addressing)

SMTP (требует e-mail аккаунт)

JMS (будет рассматриватся в лекции про очереди сообщений)

XMPP (jabber сервера http://xmpp.org/ )

Кодогенерация – для упрощения вызова удаленных сервисов и публикации своих.

52

Page 53: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ53

Web.Service. Java. AXIS

Используется библиотека Apache Axis2

Доступна для скачивания http://ws.apache.org/axis/

Включает в себя

Сервер, для запуска Веб-сервисов

Сервер, для встраивания в Tomcat

Поддержка WSDL

Средства генерации Java-классов по WSDL

Для написания сервера необходимо:

Написания Java-класса «сервера»

Запуска сервера либо в составе J2EE сервера, либо Online

Для запуска Online необходимо воспользоваться классом org.apache.axis2.engine.AxisServer

Сервис будет доступен по адресу http://localhost:6060/axis/services/ИмяКласса

Где ИмяКласса – имя вашего класса, который вы опубликовали в виде сервиса.

Page 54: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ54

Web.Service. Java. AXIS. Сервер

1. public class MyService {

2. // все public методы станут доступны как методы веб-сервиса (очень удобно)

3. public int[] doHelloWorld(int[] src)

4. {

5. int[] result = new int[src.length];

6. for(int i=0;i<src.length;i++) result[i]=src[src.length-i-1];

7. return result;

8. }

9. // вообще говоря, исключения надо обрабатывать корректно

10. public static void main(String[] args) throws Exception

11. {

12. // запускаем сервис

13. new org.apache.axis2.engine.AxisServer().deployService(

14. MyService.class.getName());

15. }

16.}

Page 55: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ

AXIS2 Client

Клиент делается ещё проще: просто запускаем кодогенерацию по URI wsdl или wsdl-файлу.

java -classpath axis2-codegen-1.6.1.jar;axis2-kernel-1.6.1.jar;wsdl4j-1.6.2.jar;commons-logging-

1.1.1.jar;neethi-3.0.1.jar;axiom-api-1.2.12.jar;axiom-dom-1.2.12.jar;axiom-impl-

1.2.12.jar;XmlSchema-1.4.7.jar;axis2-adb-codegen-1.6.1.jar;axis2-adb-1.6.1.jar

org.apache.axis2.wsdl.WSDL2Java -uri http://localhost:6060/axis2/services/MyServer?wsdl

Получается набор файлов:

MyServiceStub.java – заглушка сервиса

MyServiceStubExceptionException0.java – исключение, генерируемое сервисом

MyServiceStubCallbackHandler.java – callback объект для неблокируемых вызовов

55

Page 56: МАИ, Сети ЭВМ, Лекция №7

МАИ, каф 806, Сети ЭВМ56

Web.Service. Java. AXIS. Клиент

1. import org.apache.ws.axis2.MyServiceStub;

2. public class MyClient

3. {

4. public static void main(String[] argv) throws Exception

5. {

6. MyServiceStub stub = new MyServiceStub();

7. MyServiceStub.DoHelloWorld request = new MyServiceStub.DoHelloWorld();

8. request.setSrc(new int[] {1,2,3,4,5});

9. MyServiceStub.DoHelloWorldResponse result = stub.doHelloWorld(request);

10. if(result!=null)

11. {

12. if(result.get_return()!=null)

13. for(int i=0;i<result.get_return().length;i++)

14. System.out.println("["+result.get_return()[i]+"]");

15. }

16. }

17.}