Пример WCF
Всем доброго времени суток. На связи Алексей Гулынин. В прошлой статье мы рассмотрели как работать с HTTP-протоколом в C#. В данной статье я бы хотел написать простой пример WCF-службы. Сначала немного теории. Веб-служба — это некая компонента, которая работает на сервере и представляет из себя набор методов. Данные методы можно вызывать. Есть также понятие веб-сервисов. Веб-сервис — это способ удаленного вызова таких методов. Данные методы вызываются с использованием протокола HTTP. Как это работает?
Клиент посылает запрос по адресу службы на сервер, на котором она работает. В рамках данного запроса передаётся имя метода и параметры этого метода. Этот метод на сервере выполняется и возвращается результат. В данном случае, в качестве формата передачи данных, используется SOAP, т.е. передаются сериализованные данные.
С помощью атрибутов "DataContract()" и "DataMember()" можно указать какие свойства класса будут сериализоваться, а какие нет. Если на классе висит атрибут "DataContract()", то на все свойства, которые необходимо сериализовать, нужно навесить атрибут "DataMember()". Те свойства, где этого атрибута не будет, сериализоваться не будут.
Протокол HTTP и формат SOAP являются платформонезависимыми, поэтому веб-службы можно разрабатывать с использованием различных технологий. Такая служба может быть написана на одном языке, а клиент, который с ней будет работать — на другом.
В .NET Framework для создания служб существует специальная библиотека — WCF ("Windows Communication Foundation"). Эта библиотека позволяет создавать любые службы (не только веб), которые работают по любым протоколам и используют любые форматы передачи данных.
WCF-служба — это файл с расширением ".svc", который является заглушкой. Этот файл содержит ссылку на другой файл, реализующий логику работы службы и имя класса, который эту службу реализует.
Код состоит из двух частей:
1) Интерфейс, в котором описывается то, как эта служба будет видна снаружи, т.е. это то, что увидит клиент. Данный интерфейс размечен специальными атрибутами. Атрибут "ServiceContract" говорит о том, что это служба. На каждом методе должен быть атрибут "OperationContract". Не все методы, которые описаны в данном интерфейсе, будут являться методами веб-службы. Если на методе будет отсутствовать атрибут "OperationContract", то клиент ничего не будет знать про этот метод.
2) Класс, который реализует этот интерфейс.
Давайте напишем простую веб-службу, чтобы понять, как этот механизм работает. Клиент будет передавать службе 2 числа, и метод, который необходимо вызвать. На сервере будет реализовано 2 метода (сложение и умножение), каждый из которых будет возвращать результат клиенту. Писать будем, не используя шаблон, который есть по умолчанию в "Visual Studio". Это будет 2 простых консольных приложения.
Серверная часть:
using System; using System.Text; // Обратите внимание, данную библиотеку нужно будет подключить using System.ServiceModel; namespace Server { [ServiceContract] public interface IMyService { // Далее идут 2 метода, которые будем запрашивать у службы // Просто опишем их, реализовывать будем в классе // Сложение [OperationContract] double GetSum(double i, double j); // Умножение [OperationContract] double GetMult(double i, double j); } // Реализация методов, которые описаны в интерфейсе public class MyService : IMyService { public double GetSum(double i, double j) { return i + j; } public double GetMult(double i, double j) { return i * j; } } class Program { static void Main(string[] args) { // Инициализируем службу, указываем адрес, по которому она будет доступна ServiceHost host = new ServiceHost(typeof(MyService), new Uri("http://localhost:8000/MyService")); // Добавляем конечную точку службы с заданным интерфейсом, привязкой (создаём новую) и адресом конечной точки host.AddServiceEndpoint(typeof(IMyService), new BasicHttpBinding(), ""); // Запускаем службу host.Open(); Console.WriteLine("Сервер запущен"); Console.ReadLine(); // Закрываем службу host.Close(); } } }
Реализация клиентской части:
using System; using System.ServiceModel; namespace Client { // Тоже сюда закинул интерфейс, можно выделить в отдельную библиотеку [ServiceContract] public interface IMyService { // Сложение [OperationContract] double GetSum(double i, double j); // Умножение [OperationContract] double GetMult(double i, double j); } class Program { static void Main(string[] args) { // Задаём адрес нашей службы Uri tcpUri = new Uri("http://localhost:8000/MyService"); // Создаём сетевой адрес, с которым клиент будет взаимодействовать EndpointAddress address = new EndpointAddress(tcpUri); BasicHttpBinding binding = new BasicHttpBinding(); // Данный класс используется клиентами для отправки сообщений ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(binding, address); // Открываем канал для общения клиента с со службой IMyService service = factory.CreateChannel(); Console.WriteLine(service.GetSum(3, 5)); Console.WriteLine(service.GetSum(5, 12)); Console.WriteLine(service.GetMult(3, 5)); Console.WriteLine(service.GetMult(-3, 15)); Console.ReadLine(); } } }
Давайте проверим наш пример. Для того, чтобы всё работало необходимо сначала запустить службу, а затем клиента.
В качестве домашнего задания: добавьте 2 метода, которые реализуют операции деления и вычитания.
В данной статье вы узнали, как написать простую веб-службу, используя WCF.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.