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



WCF предоставляет высокоуровневые средства, позволяющие выбрать тип привязки для службы (протокол и формат передаваемых данных).

 

Используем IWeatherService интерфейс (был рассмотрен ранее) и реализуем возможность приема параметров и выдачи результата в текстовом формате. Пусть результатом работы метода будет XML.

Один из способов получить результат в виде XML – это определить необходимые атрибуты: для класса – XmlRoot, для данных класса, которые необходимо преобразовать – XmlAttribute или XmlElement (отличаются видом формируемых в XML сущностей).

 

[XmlRoot]

publicclassWeatherInfo

{

public WeatherInfo()

{

}

 

[XmlAttribute]

publicdouble Temperature { get; set; }

 

[XmlAttribute]

publicdouble Humidity { get; set; }

 

[XmlAttribute]

publicdouble Pressure { get; set; }

}

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

Ожидаемый службой запрос будет выглядеть следующим образом:

 

<?xmlversion="1.0"encoding="utf-8" ?>

<ServiceRequest>

<EntryPointClassName="WeatherService"MethodName="GetTemperature"/>

<Parameters>

<ParameterValue="Minsk"/>

</Parameters>

</ServiceRequest>

 

EntryPoint – точка доступа, которая содержит имя класса, вызываемый метод класса и параметры метода.

Примеррезультатавызова

<?xmlversion="1.0"encoding="utf-8" ?>

<ServiceResponse>15</ServiceResponse>

Примерреализациислужбы

classProgram

{

staticDictionary<string, Type> Services;

 

staticvoid Main(string[] args)

{

   Services = newDictionary<string, Type>();

Type type = typeof(WeatherService);

   Services.Add(type.Name, type);

 

IPAddress address = IPAddress.Parse("127.0.0.1");

int port = 8338;

TcpListener listener = newTcpListener(address, port);

   listener.Start();

try

   {

while (true)

       {

TcpClient client = listener.AcceptTcpClient();

try

           {

               ReceiveRequestAndSendResponse(client);

           }

finally

           {

               client.Close();

           }

       }

   }

finally

   {

       listener.Stop();

   }

}

 

 

privatestaticvoid ReceiveRequestAndSendResponse(TcpClient client)

{

NetworkStream stream = client.GetStream();

XElement request = XElement.Load(stream);

 

XElement entryPoint = request.XPathSelectElement("./EntryPoint");

string className = entryPoint.Attribute("ClassName").Value;

string methodName = entryPoint.Attribute("MethodName").Value;

XElement parametersXml = request.XPathSelectElement("./Parameters");

string[] parameters = parametersXml.Descendants().Select(

       x => x.Attribute(XName.Get("Value")).Value).ToArray();

 

Type serviceType;

if (Services.TryGetValue(className, out serviceType))

   {

ConstructorInfo constructor = serviceType.GetConstructor(

newType[0]);

object serviceInstance = constructor.Invoke(null);

MethodInfo method = serviceType.GetMethod(methodName);

if (method != null)

       {

object result = method.Invoke(

               serviceInstance, parameters);

var response = newXElement("ServiceResponse", result);

           response.Save(stream);

           client.Client.Shutdown(SocketShutdown.Send);

}

   }

}

}

 

После записи вызывается Shutdown для окончания операции и закрытия потока, чтобы клиент получил результат, прочитав признак конца файла.

 

Метод ReceiveRequestAndSendResponse вызывается в бесконечном цикле и обеспечивает прием и обработку входящих запросов от пользователей. В данном примере используется режим работы службы в один поток на каждого клиента, поскольку входящие запросы принимаются и выполняются в цикле. На каждого клиента создается отдельный экземпляр объекта службы – на каждый вызов конструируется отдельный объект.

Программа-клиент

 

staticvoidMain(string[] args)

{

var request =

newXElement("ServiceRequest",

newXElement("EntryPoint",

newXAttribute("ClassName", "WeatherService"),

newXAttribute("MethodName", "GetTemperature")),

newXElement("Parameters",

newXElement("Parameter",

newXAttribute("Value", "Minsk"))));

 

IPAddress address = IPAddress.Parse("127.0.0.1");

int port = 8338;

TcpClient client = newTcpClient();

client.Connect(address, port);

 

NetworkStream stream = client.GetStream();

request.Save(stream);

client.Client.Shutdown(SocketShutdown.Send);

XElement response = XElement.Load(stream);

stream.Close();

client.Close();

 

Console.WriteLine("Результатвызова WeatherService.GetTemperature = {0}",

response.Value);

Console.ReadLine();

}

 

Рассмотренный пример показывает в миниатюре принцип работы технологии WCF. По похожему принципу работает и WCF, и веб-службы вообще.

 


Дата добавления: 2018-08-06; просмотров: 259; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!