Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
[ПСП] Учебник WCF.docx
Скачиваний:
48
Добавлен:
26.03.2016
Размер:
147.76 Кб
Скачать

Как размещать и запускать базовую службу WindowsCommunicationFoundation

Это третий из шести шагов, необходимый для создания приложения Windows Communication Foundation (WCF). В этом разделе описывается размещение службы Windows Communication Foundation (WCF) в консольном приложении. Эта процедура состоит из следующих шагов:

  • Создайте консольное приложение для размещения службы.

  • Создайте узел службы для данной службы.

  • Включите обмен метаданными.

  • Откройте узел службы.

Полный список кодов, составленных при выполнении этой задачи, приведен в примере после описания процедуры.

Создание консольного приложения для размещения службы.

  1. Создайте новый проект консольного приложения, щелкнув правой кнопкой мыши на решении GettingStarted и выбрав элементы Добавить ->Создать проект. В диалоговом окне Добавить новый проект в левой части окна выберите Windows во вкладке C#. В центральной части диалогового окна выберите Консольное приложение. Задайте имя для проекта GettingStartedHost.

  2. Выберите требуемую версию .NET Framework для GettingStartedHost — .NET Framework 4.5, щелкнув правой кнопкой мыши GettingStartedHost в обозревателе решений и выбрав элемент Свойства. В раскрывающемся списке Требуемая версия .NET Framework выберите значение .NET Framework 4.5. Установка требуемой версии .NET Framework для проекта Visual Basic несколько отличается от варианта, приведенного выше. В диалоговом окне «Свойства» проекта GettingStartedHost перейдите на вкладку Компиляция, а затем нажмите кнопку Дополнительные параметры компиляции в нижнем левом углу диалогового окна. Выберите пункт .NET Framework 4.5 в раскрывающемся списке Требуемая версия .Net Framework.

Указание требуемой версии .NET Framework приведет к перезагрузке решения в среде Visual Studio 2012. Нажмите кнопку ОК, когда появится соответствующий запрос.

  1. Добавьте ссылку на проект GettingStartedLib в проект GettingStartedHost, щелкните правой кнопкой мыши папку Ссылки в проекте GettingStartedHost в обозревателе решений и выберите Добавить ссылку. В диалоговом окне Добавить ссылку выберите Решение на левой стороне диалогового окна, выберите GettingStartedLib в центральной части окна и нажмите кнопку Добавить. Это делает типы, определенные в GettingStartedLib, доступными в проекте GettingStartedHost.

  2. Добавьте в проект GettingStartedHost ссылку на сборку System.ServiceModel. Для этого в обозревателе решений щелкните правой кнопкой мыши папку Ссылка проекта GettingStartedHost и выберите пункт Добавить ссылку. В диалоговом окне Добавить ссылку выберите в левой стороне диалогового окна пункт Платформа. В текстовом поле «Поиск сборок» введите System.ServiceModel. В центральной части диалогового окна выберите System.ServiceModel, нажмите кнопку Добавить, а затем кнопку Закрыть. Сохраните решение, нажав кнопку Сохранить все под главным меню.

Размещение службы

Откройте файл Program.cs или Module.vb и введите следующий код:

// program.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.ServiceModel;

using GettingStartedLib;

using System.ServiceModel.Description;

namespace GettingStartedHost

{

class Program

{

static void Main(string[] args)

{

// Step 1 Create a URI to serve as the base address.

Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");

// Step 2 Create a ServiceHost instance

ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

try

{

// Step 3 Add a service endpoint.

selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");

// Step 4 Enable metadata exchange.

ServiceMetadataBehavior smb = new ServiceMetadataBehavior();

smb.HttpGetEnabled = true;

selfHost.Description.Behaviors.Add(smb);

// Step 5 Start the service.

selfHost.Open();

Console.WriteLine("The service is ready.");

Console.WriteLine("Press <ENTER> to terminate service.");

Console.WriteLine();

Console.ReadLine();

// Close the ServiceHostBase to shutdown the service.

selfHost.Close();

}

catch (CommunicationException ce)

{

Console.WriteLine("An exception occurred: {0}", ce.Message);

selfHost.Abort();

}

}

}

}

‘Module1.vb

Imports System

Imports System.ServiceModel

Imports System.ServiceModel.Description

Imports GettingStartedLibVB.GettingStartedLib

Module Service

Class Program

Shared Sub Main()

' Step 1 Create a URI to serve as the base address

Dim baseAddress As New Uri("http://localhost:8000/ServiceModelSamples/Service")

' Step 2 Create a ServiceHost instance

Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)

Try

' Step 3 Add a service endpoint

' Add a service endpoint

selfHost.AddServiceEndpoint( _

GetType(ICalculator), _

New WSHttpBinding(), _

"CalculatorService")

' Step 4 Enable metadata exchange.

Dim smb As New ServiceMetadataBehavior()

smb.HttpGetEnabled = True

selfHost.Description.Behaviors.Add(smb)

' Step 5 Start the service

selfHost.Open()

Console.WriteLine("The service is ready.")

Console.WriteLine("Press <ENTER> to terminate service.")

Console.WriteLine()

Console.ReadLine()

' Close the ServiceHostBase to shutdown the service.

selfHost.Close()

Catch ce As CommunicationException

Console.WriteLine("An exception occurred: {0}", ce.Message)

selfHost.Abort()

End Try

End Sub

End Class

End Module

  1. Шаг 1 - Создание экземпляра класса с именем с базовым адресом службы. Службы задаются URL-адресом, содержащим базовый адрес и дополнительный универсальный код ресурса (URI). Базовый адрес формируется следующим образом: [транспорт]://[имя компьютера или домена][:необязательно порт #]/[необязательный фрагмент универсального кода ресурса (URI)]. Базовый адрес службы калькулятора использует транспорт HTTP, localhost, порт 8000, и сегмент URI «приступая к работе»

  2. Шаг 2 — создает экземпляр класса ServiceHost для размещения службы. Конструктор принимает 2 параметра: тип класса, который реализует контракт службы, и базовый адрес службы.

  3. Шаг 3 — создает новый экземпляр ServiceEndpoint.Конечная точка — это комбинация контракта службы, привязки и адреса.Таким образом, конструктор ServiceEndpoint принимает тип интерфейса контракта службы, привязки и адреса конечной точки. Контракт службы — ICalculator, который вы определили в реализации типа службы. В этом образце используется встроенная привязка WSHttpBinding, подключаемая к конечным точкам, соответствующим спецификациями WS-*.Дополнительные сведения об WCF см. в разделе Общие сведения о привязках Windows Communication Foundation.Адрес добавляется к базовому адресу для определения конечной точки. Адрес, указанный в этом коде “Calculator”, полный адрес конечной точки “http://localhost:8000/GettingStartedService/Calculator”

    Важно

    Добавление конечной точки службы не обязательно при использовании .NET Framework 4 или более поздней версии. Если конечные точки не заданы в коде или в конфигурации, то среда выполнения добавляет одну конечную точку по умолчанию для каждого базового адреса в каждом реализованном контракте службы. Дополнительные сведения о конечных точках метаданных см. в разделе Задание адреса конечной точки.Дополнительные сведения о о конечных точках по умолчанию, привязках и поведениях см. в разделах Упрощенная конфигурация и Упрощенная конфигурация служб WCF.

  4. Шаг 4 — включение обмена метаданными. Клиенты могут использовать обмен метаданными для создания прокси-объектов, которые будут использоваться для вызова операции службы. Для поддержки обмена метаданными создайте экземпляр ServiceMetadataBehavior, установите HttpGetEnabled в значении true, добавьте поведение в коллекцию Behaviors экземпляр ServiceHost.

  5. Шаг 5 — откройте ServiceHost, чтобы прослушивать входящие сообщения.Обратите внимание, что код ожидает пока пользователь не нажмет ENTER.Если этого не сделать, то приложение немедленно закроется и служба завершит работу. Также обратите внимание, что используется блок try/catch. После создания экземпляра ServiceHost весь следующий код помещается в блок try/catch. Дополнительные сведения о перехвате исключений, формируемых системой безопасности ServiceHost см. в разделе Предотвращение проблем при использовании операторов

Проверка работы службы

  1. Запустите консольное приложение GettingStartedHost из Visual Studio 2012. В Windows Vista и более поздних операционных системах служба должна запускаться пользователем с правами администратора. Так как Visual Studio была запущена пользователем с правами администратора, GettingStartedHost также запускается пользователем с правами администратора. Вы также можете запустить новую командную строку с правами администратора, а затем в ней запустить service.exe.

  2. Откройте Internet Explorer и перейдите на страницу отладки службы по адресу. http://localhost:8000/GettingStarted/

Пример

Нижеприведенный пример иллюстрирует создание контракта службы и ее реализацию (см. предыдущие шаги в руководстве), а также размещение службы в консольном приложении.

Для компиляции с помощью компилятора командной строки скомпилируйте IService1.cs и Service2.cs в библиотеку классов, ссылающуюся на System.ServiceModel.dll. и скомпилируйте Program.cs в консольное приложение.

// IService1.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;

namespace GettingStartedLib

{

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]

public interface ICalculator

{

[OperationContract]

double Add(double n1, double n2);

[OperationContract]

double Subtract(double n1, double n2);

[OperationContract]

double Multiply(double n1, double n2);

[OperationContract]

double Divide(double n1, double n2);

}

}

// Service1.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;

namespace GettingStartedLib

{

public class CalculatorService : ICalculator

{

public double Add(double n1, double n2)

{

double result = n1 + n2;

Console.WriteLine("Received Add({0},{1})", n1, n2);

// Code added to write output to the console window.

Console.WriteLine("Return: {0}", result);

return result;

}

public double Subtract(double n1, double n2)

{

double result = n1 - n2;

Console.WriteLine("Received Subtract({0},{1})", n1, n2);

Console.WriteLine("Return: {0}", result);

return result;

}

public double Multiply(double n1, double n2)

{

double result = n1 * n2;

Console.WriteLine("Received Multiply({0},{1})", n1, n2);

Console.WriteLine("Return: {0}", result);

return result;

}

public double Divide(double n1, double n2)

{

double result = n1 / n2;

Console.WriteLine("Received Divide({0},{1})", n1, n2);

Console.WriteLine("Return: {0}", result);

return result;

}

}

}

//Program.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.ServiceModel;

using GettingStartedLib;

using System.ServiceModel.Description;

namespace GettingStartedHost

{

class Program

{

static void Main(string[] args)

{

// Step 1 of the address configuration procedure: Create a URI to serve as the base address.

Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");

// Step 2 of the hosting procedure: Create ServiceHost

ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

try

{

// Step 3 of the hosting procedure: Add a service endpoint.

selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");

// Step 4 of the hosting procedure: Enable metadata exchange.

ServiceMetadataBehavior smb = new ServiceMetadataBehavior();

smb.HttpGetEnabled = true;

selfHost.Description.Behaviors.Add(smb);

// Step 5 of the hosting procedure: Start (and then stop) the service.

selfHost.Open();

Console.WriteLine("The service is ready.");

Console.WriteLine("Press <ENTER> to terminate service.");

Console.WriteLine();

Console.ReadLine();

// Close the ServiceHostBase to shutdown the service.

selfHost.Close();

}

catch (CommunicationException ce)

{

Console.WriteLine("An exception occurred: {0}", ce.Message);

selfHost.Abort();

}

}

}

}

‘IService1.vb

Imports System

Imports System.ServiceModel

Namespace GettingStartedLib

<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _

Public Interface ICalculator

<OperationContract()> _

Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double

<OperationContract()> _

Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double

<OperationContract()> _

Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double

<OperationContract()> _

Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double

End Interface

End Namespace

‘Service1.vb

Imports System

Imports System.ServiceModel

Namespace GettingStartedLib

Public Class CalculatorService

Implements ICalculator

Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add

Dim result As Double = n1 + n2

' Code added to write output to the console window.

Console.WriteLine("Received Add({0},{1})", n1, n2)

Console.WriteLine("Return: {0}", result)

Return result

End Function

Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract

Dim result As Double = n1 - n2

Console.WriteLine("Received Subtract({0},{1})", n1, n2)

Console.WriteLine("Return: {0}", result)

Return result

End Function

Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply

Dim result As Double = n1 * n2

Console.WriteLine("Received Multiply({0},{1})", n1, n2)

Console.WriteLine("Return: {0}", result)

Return result

End Function

Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide

Dim result As Double = n1 / n2

Console.WriteLine("Received Divide({0},{1})", n1, n2)

Console.WriteLine("Return: {0}", result)

Return result

End Function

End Class

End Namespace

‘Module1.vb

Imports System

Imports System.ServiceModel

Imports System.ServiceModel.Description

Imports GettingStartedLibVB.GettingStartedLib

Module Service

Class Program

Shared Sub Main()

' Step 1 of the address configuration procedure: Create a URI to serve as the base address.

Dim baseAddress As New Uri("http://localhost:8000/ServiceModelSamples/Service")

' Step 2 of the hosting procedure: Create ServiceHost

Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)

Try

' Step 3 of the hosting procedure: Add a service endpoint.

' Add a service endpoint

selfHost.AddServiceEndpoint( _

GetType(ICalculator), _

New WSHttpBinding(), _

"CalculatorService")

' Step 4 of the hosting procedure: Enable metadata exchange.

' Enable metadata exchange

Dim smb As New ServiceMetadataBehavior()

smb.HttpGetEnabled = True

selfHost.Description.Behaviors.Add(smb)

' Step 5 of the hosting procedure: Start (and then stop) the service.

selfHost.Open()

Console.WriteLine("The service is ready.")

Console.WriteLine("Press <ENTER> to terminate service.")

Console.WriteLine()

Console.ReadLine()

' Close the ServiceHostBase to shutdown the service.

selfHost.Close()

Catch ce As CommunicationException

Console.WriteLine("An exception occurred: {0}", ce.Message)

selfHost.Abort()

End Try

End Sub

End Class

End Module

Примечание

Подобные службы требуют разрешения на регистрацию на компьютере HTTP-адресов, на которые будет ожидаться передача данных. Учетные записи с уровнем доступа администратора имеют данное разрешение, а остальным учетным записям должно быть предоставлено разрешение на использование пространства имен HTTP. Дополнительные сведения о настройке резервирования пространства имен см. в разделе Настройка HTTP и HTTPS. Запуск файла service.exe на Visual Studio возможен только при наличии прав администратора.

Сейчас служба запущена.Перейти к Как создать клиент Windows Communication Foundation.Сведения по устранению неполадок см. в разделе Устранение неполадок, связанных с учебником по началу работы.