Использование WCF

WCF (Windows Communication Foundation) - технология от Microsoft, призванная лечь в основу передачи данных между приложениями, а также реализовать взаимодействие между ними по сети. Передавать данные с помощью этой технологии можно между двумя ее частями - клиентом и службой. Служба это кусок кода, который что-то умеет и чем-то обладает. А клиент - он знает, что умеет служба и чем обладает и может этим пользоваться.

Если мы хотим обмениваться данными между какими то рабочими процессами, будь то программы на разных компьютерах, службы на сервере IIS и их пользователи или просто внутри Windows между потоками или программами что-то передать - можно подумать про WCF.
Когда мы описываем сервис, мы должны указать точки входа (endpoints). Точек может быть сколько угодно. Каждая точка имеет 3 компонента (адрес, контракт, привязка).

В WCF есть 3 ключевых понятия:
  • Address (адрес, отвечает на вопрос "где") – В качестве адреса выступает URI - идентификатор. Это может быть обычный адрес протокола HTTP, например: http://localhost:8999/myservice - служба будет находиться на локальной машине, на порту 8999 и доступна клиенту по протоколу http. Адрес не задает формата обмена и условий, это просто идентификатор. Но в то же время, в зависимости от привязки адрес должен быть сформирован определенным образом. В данном примере он корректен для обмена по протоколу http. Если планируется передавать данные по низкому TCP, адрес должен начинаться так: net.tcp://localhost/myservice. Если его указать в качестве адреса службы, то клиент будет искать службу по такому адресу. Итак, адрес - это то, где клиенту искать службу.
  • Contract (контракт, отвечает на вопрос "что") - В основе взаимодействия между клиентом и службой лежат контракты. Контракты - это нечто общее, о чем должны знать обе стороны, чтобы этим пользоваться и понимать друг друга. Это интерфейс, описанный с использованием атрибутов.
  • Binding (привязка, отвечает на вопрос "как") - Определяет как будут взаимодействовать клиент и служба. По какому протоколу они будут обмениваться информацией, настройки протокола, безопасность, кодировка, и многое другое.
Рассмотрим пример небольшого сервиса.
App.config (конфигурационный файл)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary1.Service1">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8000/MyService/" />
          </baseAddresses>
        </host>
        <endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1">
        </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
IService.cs
     [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);
    }
ServiceContract - означает, что на основе данного интерфейса будет осуществляться взаимодействие между клиентом и службой. Данными методами сможет пользоваться клиент, а они будут выполняться на стороне службы. Методы, помеченные [OperationContract] будут известны обеим сторонам.
Service.cs
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }
    }
Рассмотрим пример небольшого TCP сервера, реализованного с помощью сокетов. Сервер будет принимать строку, и возвращать ее клиенту.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace TCPServer
{
    class Program
    {
        static void Main(string[] args)
        {
            int port = 3333;
            int countConnects = 10;

            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint pointListenInputsConnects = new IPEndPoint(IPAddress.Any, port);
            server.Bind(pointListenInputsConnects);
            server.Listen(countConnects);

            while (true)
            {
                Socket inputClient = server.Accept();
                if (inputClient.Available > 0)
                {
                    byte[] inputText = new byte[inputClient.Available]; 
                    inputClient.Receive(inputText);
                    inputClient.Send(inputText);
                    inputClient.Close();
                }
            }
        }
    }
}

Last edited Feb 24, 2012 at 10:23 AM by basph, version 2

Comments

No comments yet.