
Национальный исследовательский институт
Московский Энергетический Институт (Технический Университет)
Институт автоматики и вычислительной техники
Кафедра Прикладной математики
Лабораторная работа №1
по дисциплине «Проектирование крупных распределенных программных систем и баз данных»
тема: «Разработка сервиса с применением WCF (WCF Service Application)»
Выполнил:
Машеров Д.Е.
Проверил:
к.т.н., доц. Куриленко И.Е.
Москва
2012 г.
-
Понятия wcf,wsdl,soap
Windows Communication Foundation (WCF) — программный фреймворк, используемый для обмена данными между приложениями входящими в состав .NET Framework. До своего выпуска в декабре 2006 года в составе .NET Framework 3.0, WCF был известен под кодовым именем Indigo.
WCF делает возможным построение безопасных и надёжных транзакционных систем через упрощённую унифицированную программную модель межплатформенного взаимодействия. Комбинируя функциональность существующих технологий .NET по разработке распределённых приложений (ASP.NET XML Web Services — ASMX, WSE 3.0, .NET Remoting, .NET Enterprise Services и System.Messaging), WCF предоставляет единую инфраструктуру разработки, при умелом применении повышающую производительность и снижающую затраты на создание безопасных, надёжных и транзакционных Web-служб нового поколения. Заложенные в неё принципы интероперабельности позволяют организовать работу с другими платформами, для чего используются технологии взаимодействия платформ, например WSIT разрабатываемые на базе открытого исходного кода.
WSDL (англ. Web Services Description Language) — язык описания веб-сервисов и доступа к ним, основанный на языке XML.
Каждый документ WSDL можно разбить на следующие логические части:
-
определение типов данных (types) — определение вида отправляемых и получаемых сервисом XML сообщений
-
элементы данных (message) — сообщения, используемые web-сервисом
-
абстрактные операции (portType) — список операций, которые могут быть выполнены с сообщениями
-
связывание сервисов (binding) — способ, которым сообщение будет доставлено
SOAP (от англ. Simple Object Access Protocol — простой протокол доступа к объектам; вплоть до спецификации 1.2) — протокол обмена структурированными сообщениями в распределённой вычислительной среде. Первоначально SOAP предназначался в основном для реализации удалённого вызова процедур (RPC). Сейчас протокол используется для обмена произвольными сообщениями в формате XML, а не только для вызова процедур. Официальная спецификация последней версии 1.2 протокола никак не расшифровывает название SOAP. SOAP является расширением протокола XML-RPC.
SOAP может использоваться с любым протоколом прикладного уровня: SMTP, FTP, HTTP, HTTPS и др. Однако его взаимодействие с каждым из этих протоколов имеет свои особенности, которые должны быть определены отдельно. Чаще всего SOAP используется поверх HTTP.
SOAP является одним из стандартов, на которых базируются технологии веб-служб.
-
Задание
-
Создать приложение сервера
-
Создать клиентское приложение
-
Организовать передачу событий сервера на клиент
В среде Visual Studio был создан сервис, реализующий подсчет расстояния между точками в двумерной системе, и клиентское приложение.
Был реализован интерфейсы, в котором был определен контракты сервиса:
[ServiceContract(CallbackContract = typeof(IClientCallback))]
public interface IMathService
{
[OperationContract]
double Distance(double x1, double x2, double y1, double y2);
[OperationContract]
double DotProduct(double x1, double x2, double y1, double y2);
[OperationContract(IsOneWay = true)]
void Register();
[OperationContract(IsOneWay = true)]
void Leave();
[OperationContract(IsOneWay = true)]
void SendLog();
}
Класс ServiceContract показывает, что интерфейс или класс определяет контракт службы в a Windows Communication Foundation (WCF) приложения. Атрибут CallbackContract возвращает или задает тип контракта обратного вызова, если контракт является дуплексным.
Значение свойства IsOneWay=true, значит, что этот метод получает сообщение запроса и не возвращает ответное сообщение.
Также создан интерфейс обратного вызова:
public interface IClientCallback
{
[OperationContract(IsOneWay = true)]
void Log(string log);
}
Создан класс, реализующий интерфейс контрактов
public class MathService : ImathService
{
…
}
В файле конфигурации была прописана привязка wsDualHttpBinding.
wsDualHttpBinding - безопасная привязка с возможностью взаимодействия, которая предназначена для использования с дуплексными контрактами служб и службы и клиенты, которая позволяет отправлять и получать сообщения.
<endpoint address="e1" binding="wsDualHttpBinding" bindingConfiguration=""
name="Endpoint1" contract="MathService.IMathService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
Клиентское приложение:
Добавлена ссылка на сервис, при этом был сгенерирован прокси класс.
Рализован интерфейс обратного вызова:
public class CallbackHandler : IMathServiceCallback
С помощью него вызывается метод, предоставляемый сервером.
С помощью класса InstanceContext был создан экземпляр класса клиента.
InstanceContext instanceContext = new InstanceContext(new CallbackHandler(this));
client = new MathServiceClient(instanceContext, "Endpoint1");
WSDL сервиса можно посмотреть через ссылку
http://localhost:8732/Design_Time_Addresses/MathService/MathService/?wsdl
-
Код
-
Интерфейсы сервиса:
[ServiceContract(CallbackContract = typeof(IClientCallback))]
public interface IMathService
{
[OperationContract]
double Distance(double x1, double x2, double y1, double y2);
[OperationContract]
double DotProduct(double x1, double x2, double y1, double y2);
[OperationContract(IsOneWay = true)]
void Register();
[OperationContract(IsOneWay = true)]
void Leave();
[OperationContract(IsOneWay = true)]
void SendLog();
}
public interface IClientCallback
{
[OperationContract(IsOneWay = true)]
void Log(string log);
}
Класс, реализующий интерфейс
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MathService : IMathService
{
static string log = "";
static List<IClientCallback> clientCallbacks = new List<IClientCallback>();
public double Distance(double x1, double x2, double y1, double y2)
{
log = calledFunction("Distance", new string[] { x1.ToString(), x2.ToString(),y1.ToString(), y2.ToString() }) + log;
return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
public double DotProduct(double x1, double x2, double y1, double y2)
{
clientCallbacks.Add(OperationContext.Current.GetCallbackChannel<IClientCallback>());
log = calledFunction("DotProduct", new string[] { x1.ToString(), x2.ToString(), y1.ToString(), y2.ToString() }) + log;
return Math.Sqrt(x1*x2 + y1*y2);
}
public void Register()
{
clientCallbacks.Add(OperationContext.Current.GetCallbackChannel<IClientCallback>());
SendLog();
}
public void Leave()
{
clientCallbacks.Remove(OperationContext.Current.GetCallbackChannel<IClientCallback>());
SendLog();
}
public void SendLog()
{
foreach (IClientCallback clientCallback in clientCallbacks)
clientCallback.Log(log);
}
private string calledFunction(string Function, string[] args)
{
return "Called Function: " + Function + Environment.NewLine +
"Arguments: " + args.Aggregate((current, next) => current + ", " + next) + Environment.NewLine;
}