Реализация собственного протокола взаимодействия клиента и службы
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; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!