Нестабильная система с очередями связи

В примере "Нестабильный пример" демонстрируется, как выполнять очередную связь с изменчивыми параметрами через транспорт очереди сообщений (MSMQ). В этом примере используется NetMsmqBinding. Служба в этом случае — это локальное консольное приложение, позволяющее наблюдать за службой, получающей сообщения в очереди.

Замечание

Процедура установки и инструкции по сборке для этого примера находятся в конце этого раздела.

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

При отправке сообщения без гарантий MSMQ делает только лучшие усилия для доставки сообщения, в отличие от гарантий "Точно один раз", где MSMQ гарантирует, что сообщение доставлено или, если оно не может быть доставлено, позволяет узнать, что сообщение не может быть доставлено.

В некоторых сценариях может потребоваться отправить нестабильное сообщение без гарантий по очереди, когда своевременное доставка важнее, чем потеря сообщений. Переменные сообщения не сохраняются после сбоя диспетчера очередей. Таким образом, если диспетчер очередей завершает работу, очередь без транзакций, используемая для хранения переменных сообщений, сохраняется, но сами сообщения не сохраняются, так как сообщения не хранятся на диске.

Замечание

Не удается отправлять переменные сообщения без гарантий в пределах области транзакции с помощью MSMQ. Для отправки летучих сообщений также необходимо создать нетранзакционную очередь.

Контракт обслуживания в этом примере — это IStockTicker, который определяет однонаправленные услуги, лучше всего подходящие для использования с очередями.

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface IStockTicker
{
    [OperationContract(IsOneWay = true)]
    void StockTick(string symbol, float price);
}

Сервисная операция отображает тикер и цену акции, как показано в следующем примере кода:

public class StockTickerService : IStockTicker
{
    public void StockTick(string symbol, float price)
    {
        Console.WriteLine("Stock Tick {0}:{1} ", symbol, price);
     }
     …
}

Служба размещена на собственных серверах. Очередь, используемую для транспорта MSMQ, необходимо создавать заранее. Это можно сделать вручную или с помощью кода. В этом примере служба содержит код для проверки наличия очереди и создания ее при необходимости. Имя очереди считывается из файла конфигурации. Базовый адрес используется средством служебной программы метаданных ServiceModel (Svcutil.exe) для создания прокси-сервера для службы.

// Host the service within this EXE console application.
public static void Main()
{
    // Get MSMQ queue name from app settings in configuration.
    string queueName = ConfigurationManager.AppSettings["queueName"];

    // Create the transacted MSMQ queue if necessary.
    if (!MessageQueue.Exists(queueName))
        MessageQueue.Create(queueName);

    // Create a ServiceHost for the StockTickerService type.
    using (ServiceHost serviceHost = new ServiceHost(typeof(StockTickerService)))
    {
        // Open the ServiceHost to create listeners and start listening for messages.
        serviceHost.Open();

        // The service can now be accessed.
        Console.WriteLine("The service is ready.");
        Console.WriteLine("Press <ENTER> to terminate service.");
        Console.WriteLine();
        Console.ReadLine();

        // Close the ServiceHost to shutdown the service.
        serviceHost.Close();
    }
}

Имя очереди MSMQ указывается в разделе appSettings файла конфигурации. Конечная точка службы определена в разделе system.serviceModel файла конфигурации и указывает привязку netMsmqBinding .

Замечание

Имя очереди содержит точку (.) для обозначения локального компьютера и использует разделители в виде обратной косой черты в пути при создании очереди с помощью System.Messaging. Адрес конечной точки Windows Communication Foundation (WCF) указывает схему net.msmq:, использует 'localhost' для обозначения локального компьютера и косые черты в пути.

Гарантии и устойчивость или волатильность сообщений также указываются в конфигурации.

<appSettings>
  <!-- use appSetting to configure MSMQ queue name -->
  <add key="queueName" value=".\private$\ServiceModelSamplesVolatile" />
</appSettings>

<system.serviceModel>
  <services>
    <service name="Microsoft.ServiceModel.Samples.StockTickerService"
             behaviorConfiguration="CalculatorServiceBehavior">
    ...
      <!-- Define NetMsmqEndpoint -->
      <endpoint address="net.msmq://localhost/private/ServiceModelSamplesVolatile"
                binding="netMsmqBinding"
                bindingConfiguration="volatileBinding"
                contract="Microsoft.ServiceModel.Samples.IStockTicker" />
    ...
    </service>
  </services>

  <bindings>
    <netMsmqBinding>
      <binding name="volatileBinding"
             durable="false"
           exactlyOnce="false"/>
    </netMsmqBinding>
  </bindings>
  ...
</system.serviceModel>

Поскольку пример отправляет сообщения, используя нетранзакционную очередь, транзакционные сообщения не могут быть отправлены в очередь.

// Create a client.
Random r = new Random(137);

StockTickerClient client = new StockTickerClient();

float price = 43.23F;
for (int i = 0; i < 10; i++)
{
    float increment = 0.01f * (r.Next(10));
    client.StockTick("zzz" + i, price + increment);
}

//Closing the client gracefully cleans up resources.
client.Close();

При запуске примера действия клиента и службы отображаются как в окнах службы, так и в консоли клиента. Вы можете увидеть, как служба получает сообщения от клиента. Нажмите клавишу ВВОД в каждом окне консоли, чтобы завершить работу службы и клиента. Обратите внимание, что поскольку используется очередь, клиенту и службе не обязательно работать одновременно. Вы можете запустить клиент, завершить его работу, а затем запустить службу, и она всё равно продолжает получать свои сообщения.

The service is ready.
Press <ENTER> to terminate service.

Stock Tick zzz0:43.25
Stock Tick zzz1:43.23
Stock Tick zzz2:43.28
Stock Tick zzz3:43.3
Stock Tick zzz4:43.23
Stock Tick zzz5:43.25
Stock Tick zzz6:43.25
Stock Tick zzz7:43.24
Stock Tick zzz8:43.32
Stock Tick zzz9:43.3

Настройка, сборка и запуск примера

  1. Убедитесь, что вы выполнили процедуру настройки One-Time для образцов Windows Communication Foundation.

  2. Чтобы создать версию решения на C# или Visual Basic .NET, следуйте инструкциям по сборке примеров Windows Communication Foundation .

  3. Чтобы запустить пример в конфигурации с одним или несколькими компьютерами, следуйте инструкциям в запуска примеров Windows Communication Foundation.

По умолчанию в NetMsmqBindingвключена транспортная безопасность. Существует два подходящих свойства для безопасности транспорта MSMQ: MsmqAuthenticationMode и MsmqProtectionLevel.. По умолчанию для режима проверки подлинности задано значение Windows, а для уровня защиты - Sign. Чтобы MSMQ предоставляла функцию проверки подлинности и подписывания, она должна быть частью домена, а параметр интеграции Active Directory для MSMQ должен быть установлен. Если запустить этот пример на компьютере, который не соответствует этим критериям, вы получите ошибку.

Запуск примера на компьютере, присоединенном к рабочей группе или без интеграции Active Directory

  1. Если компьютер не является частью домена или не имеет интеграции Active Directory, отключите транспортную безопасность, задав режим проверки подлинности и уровень None защиты, как показано в следующем примере кода конфигурации:

    <system.serviceModel>
        <services>
          <service name="Microsoft.ServiceModel.Samples.StockTickerService"
                   behaviorConfiguration="StockTickerServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
              </baseAddresses>
            </host>
    
            <!-- Define NetMsmqEndpoint -->
            <endpoint address="net.msmq://localhost/private/ServiceModelSamplesVolatile"
                      binding="netMsmqBinding"
                      bindingConfiguration="volatileBinding"
                      contract="Microsoft.ServiceModel.Samples.IStockTicker" />
            <!-- the mex endpoint is exposed at http://localhost:8000/ServiceModelSamples/service/mex -->
            <endpoint address="mex"
                      binding="mexHttpBinding"
                      contract="IMetadataExchange" />
    
          </service>
        </services>
    
        <bindings>
          <netMsmqBinding>
            <binding name="volatileBinding"
                  durable="false"
                  exactlyOnce="false">
              <security mode="None" />
            </binding>
          </netMsmqBinding>
        </bindings>
    
        <behaviors>
          <serviceBehaviors>
            <behavior name="StockTickerServiceBehavior">
              <serviceMetadata httpGetEnabled="True"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
      </system.serviceModel>
    
  2. Перед запуском примера убедитесь, что вы измените конфигурацию как на сервере, так и на клиенте.

    Замечание

    Установка security mode равносильна установке None, а также установке параметров MsmqAuthenticationMode, MsmqProtectionLevel, и Message безопасности на None.