Поделиться через


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

Это третья из шести задач, выполнение которых необходимо для создания базовой службы Windows Communication Foundation (WCF) и клиента, который может вызывать службу. Общие сведения обо всех шести задачах можно получить в разделе Учебник по началу работы.

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

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

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

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

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

Полный список кодов, составленных при выполнении этой задачи, приведен в примере после описания процедуры. Добавьте следующий код в метод Main(), определенный в классе Program. Этот класс был создан вами при создании решения Service.

Настройка базового адреса службы

  1. Создайте экземпляр Uri для базового адреса службы. Универсальный код ресурса (URI) указывает схему HTTP, локальный компьютер, номер порта 8000 и путь ServiceModelSample/Service к службе, который был указан для пространства имен службы в контракте службы.

    Dim baseAddress As New Uri("https://localhost:8000/ServiceModelSamples/Service")
    
    Uri baseAddress = new Uri("https://localhost:8000/ServiceModelSamples/Service");
    

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

  1. Импортируйте пространство имен System.ServiceModel.Description. Эта строка кода должна быть размещена в верхней части файла Program.cs/Program.vb вместе с остальными операторами using или imports.

    Imports System.ServiceModel.Description
    
    using System.ServiceModel.Description;
    
  2. Создайте новый экземпляр ServiceHost для размещения службы. Необходимо указать тип, реализующий контракт службы, и базовый адрес. В данном случае базовый адрес — https://localhost:8000/ServiceModelSamples/Service, а CalculatorService — это тип, реализующий контракт службы.

    Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)
    
    ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
    
  3. Добавьте оператор try-catch, который перехватывает CommunicationException, и добавьте код в блок try, выполнив три следующих шага. Предложение catch должно отображать сообщение об ошибке и вызвать команду selfHost.Abort().

    Try
        ' ...
    Catch ce As CommunicationException
        Console.WriteLine("An exception occurred: {0}", ce.Message)
        selfHost.Abort()
    End Try
    
    try
    {
        // ...
    }
    catch (CommunicationException ce)
    {
        Console.WriteLine("An exception occurred: {0}", ce.Message);
        selfHost.Abort();
    }
    
  4. Добавление конечной точки, предоставляющей службу. Для этого необходимо указать контракт, предоставляемый конечной точкой, привязку и адрес конечной точки. Для данного образца необходимо указать контракт ICalculator, привязку WSHttpBinding и адрес CalculatorService. Обратите внимание на то, что адрес конечной точки в данном случае — это относительный адрес. Полный адрес конечной точки представляет собой сочетание базового адреса и адреса конечной точки. В данном случае полный адрес выглядит следующим образом: https://localhost:8000/ServiceModelSamples/Service/CalculatorService.

    ' Add a service endpoint
    selfHost.AddServiceEndpoint( _
        GetType(ICalculator), _
        New WSHttpBinding(), _
        "CalculatorService")
    
    selfHost.AddServiceEndpoint(
        typeof(ICalculator),
        new WSHttpBinding(),
        "CalculatorService");
    
    ms730935.note(ru-ru,VS.100).gifПримечание
    Начиная с версии .NET Framework 4, если для службы явно не настроена ни одна конечная точка, то среда выполнения добавляет конечные точки по умолчанию, когда открывается ServiceHost. В этом примере показано, как конечная точка добавляется явно. Дополнительные сведения о конечных точках по умолчанию, привязках и поведениях см. в разделах Упрощенная конфигурация и Упрощенная конфигурация служб WCF.

  5. Включите обмен метаданными. Для этого добавьте поведение метаданных службы. Прежде всего, создайте экземпляр ServiceMetadataBehavior, установите свойство HttpGetEnabled на значение true, затем добавьте новое поведение к службе. Дополнительные сведения проблемах безопасности, возникающих при публикации метаданных, см. в разделе Security Considerations with Metadata.

    ' Enable metadata exchange
    Dim smb As New ServiceMetadataBehavior()
    smb.HttpGetEnabled = True
    selfHost.Description.Behaviors.Add(smb)
    
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    selfHost.Description.Behaviors.Add(smb);
    
  6. Откройте ServiceHost и ожидайте входящие сообщения. Когда пользователь нажмет клавишу ВВОД, закройте ServiceHost.

    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()
    
    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();
    

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

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

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

Пример

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

Не забудьте задать ссылку на System.ServiceModel.dll при компиляции кода.

Imports System
Imports System.ServiceModel
Imports System.ServiceModel.Description

Module Service
    ' Define a service contract.
    <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

    ' Service class that implements the service contract.
    ' Added code to write output to the console window.
    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
            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

    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("https://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
using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Microsoft.ServiceModel.Samples
{
    // Define a service contract.
    [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);
    }

    // Service class that implements the service contract.
    // Added code to write output to the console window.
    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            Console.WriteLine("Received Add({0},{1})", n1, n2);
            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;
        }
    }
    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("https://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();
            }

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

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

См. также

Задачи

Образец для начала работы
Резидентное размещение