Sdílet prostřednictvím


Zpracované vazby služby MSMQ

Ukázka transacted ukazuje, jak provádět transacted ve frontě komunikace pomocí služby Řízení front zpráv (MSMQ).

Poznámka:

Postup nastavení a pokyny k sestavení pro tuto ukázku najdete na konci tohoto tématu.

Ve frontě komunikace klient komunikuje se službou pomocí fronty. Přesněji řečeno, klient odesílá zprávy do fronty. Služba přijímá zprávy z fronty. Služba a klient proto nemusí být spuštěny ve stejnou dobu, aby komunikovaly pomocí fronty.

Pokud se transakce používají k odesílání a příjmu zpráv, existují ve skutečnosti dvě samostatné transakce. Když klient odesílá zprávy v rámci transakce, transakce je místní pro klienta a správce front klienta. Když služba přijímá zprávy v rámci rozsahu transakce, transakce je místní pro službu a přijímající správce fronty. Je velmi důležité si uvědomit, že klient a služba se účastní stejné transakce; místo toho používají různé transakce při provádění operací (například odesílání a přijímání) s frontou.

V této ukázce klient odešle do služby dávku zpráv z rozsahu transakce. Zprávy odeslané do fronty pak služba přijímá v rámci oboru transakce definovaného službou.

Kontrakt služby je , jak je IOrderProcessorznázorněno v následujícím vzorovém kódu. Rozhraní definuje jednosměrnou službu, která je vhodná pro použití s frontami.

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
    [OperationContract(IsOneWay = true)]
    void SubmitPurchaseOrder(PurchaseOrder po);
}

Chování služby definuje chování operace s nastavenou TransactionScopeRequired na true. Tím se zajistí, že stejný obor transakce, který se používá k načtení zprávy z fronty, budou používat správci prostředků, ke kterým tato metoda přistupuje. Také zaručuje, že pokud metoda vyvolá výjimku, zpráva se vrátí do fronty. Bez nastavení tohoto chování operace kanál ve frontě vytvoří transakci pro čtení zprávy z fronty a potvrdí ji automaticky před odesláním tak, aby v případě selhání operace byla zpráva ztracena. Nejběžnějším scénářem je, že operace služby se zařadí do transakce, která se používá ke čtení zprávy z fronty, jak je znázorněno v následujícím kódu.

 // This service class that implements the service contract.
 // This added code writes output to the console window.
public class OrderProcessorService : IOrderProcessor
 {
     [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
     public void SubmitPurchaseOrder(PurchaseOrder po)
     {
         Orders.Add(po);
         Console.WriteLine("Processing {0} ", po);
     }
  …
}

Služba je hostovaná v místním prostředí. Při použití přenosu MSMQ je nutné předem vytvořit použitou frontu. Můžete to provést ručně nebo prostřednictvím kódu. V této ukázce obsahuje služba kód pro kontrolu existence fronty a vytvoření fronty, pokud neexistuje. Název fronty se načte z konfiguračního souboru. Základní adresu používá nástroj ServiceModel Metadata Utility Tool (Svcutil.exe) k vygenerování proxy serveru do služby.

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

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

    // Create a ServiceHost for the OrderProcessorService type.
    using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
    {
        // 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 shut down the service.
        serviceHost.Close();
    }
}

Název fronty MSMQ se zadává v aplikaci Nastavení části konfiguračního souboru, jak je znázorněno v následující ukázkové konfiguraci.

<appSettings>
    <add key="queueName" value=".\private$\ServiceModelSamplesTransacted" />
</appSettings>

Poznámka:

Název fronty používá tečku (.) pro místní počítač a oddělovače zpětného lomítka v jeho cestě při vytváření fronty pomocí System.Messaging. Koncový bod WCF (Windows Communication Foundation) používá adresu fronty se schématem net.msmq, používá k označení místního počítače "localhost" a v cestě používá lomítka.

Klient vytvoří obor transakce. Komunikace s frontou probíhá v rámci transakce, což způsobuje, že se považuje za atomické jednotky, kde se všechny zprávy odesílají do fronty nebo žádné zprávy se do fronty neposílají. Transakce je potvrzena voláním Complete oboru transakce.

// Create a client.
OrderProcessorClient client = new OrderProcessorClient();

// Create the purchase order.
PurchaseOrder po = new PurchaseOrder();
po.CustomerId = "somecustomer.com";
po.PONumber = Guid.NewGuid().ToString();

PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
lineItem1.ProductId = "Blue Widget";
lineItem1.Quantity = 54;
lineItem1.UnitCost = 29.99F;

PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
lineItem2.ProductId = "Red Widget";
lineItem2.Quantity = 890;
lineItem2.UnitCost = 45.89F;

po.orderLineItems = new PurchaseOrderLineItem[2];
po.orderLineItems[0] = lineItem1;
po.orderLineItems[1] = lineItem2;

// Create a transaction scope.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
    // Make a queued call to submit the purchase order.
    client.SubmitPurchaseOrder(po);
    // Complete the transaction.
    scope.Complete();
}

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

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

Pokud chcete ověřit, že transakce fungují, upravte klienta tak, že okomentujte obor transakce, jak je znázorněno v následujícím ukázkovém kódu, znovu sestavte řešení a spusťte klienta.

//scope.Complete();

Protože transakce není dokončena, zprávy se neodesílají do fronty.

Při spuštění ukázky se aktivity klienta a služeb zobrazí v oknech služby i konzoly klienta. Můžete vidět, že služba přijímá zprávy od klienta. Stisknutím klávesy ENTER v každém okně konzoly vypnete službu a klienta. Všimněte si, že vzhledem k tomu, že se používá řízení front, nemusí být klient a služba ve stejnou dobu spuštěné. Klienta můžete spustit, vypnout a pak spustit službu a stále přijímat zprávy.

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

Processing Purchase Order: 7b31ce51-ae7c-4def-9b8b-617e4288eafd
        Customer: somecustomer.com
        OrderDetails
                Order LineItem: 54 of Blue Widget @unit price: $29.99
                Order LineItem: 890 of Red Widget @unit price: $45.89
        Total cost of this order: $42461.56
        Order status: Pending

Nastavení, sestavení a spuštění ukázky

  1. Ujistěte se, že jste pro ukázky windows Communication Foundation provedli jednorázovou instalační proceduru.

  2. Pokud je služba spuštěná jako první, zkontroluje, jestli je fronta k dispozici. Pokud fronta není k dispozici, služba ji vytvoří. Službu můžete nejprve spustit, abyste vytvořili frontu, nebo ji můžete vytvořit prostřednictvím Správce front MSMQ. Podle těchto kroků vytvořte frontu v systému Windows 2008.

    1. Otevřete Správce serveru v sadě Visual Studio 2012.

    2. Rozbalte kartu Funkce.

    3. Klikněte pravým tlačítkem myši na Soukromé fronty zpráv a vyberte Nová soukromá fronta.

    4. Zaškrtněte políčko Transactional (Transakce).

    5. Zadejte ServiceModelSamplesTransacted jako název nové fronty.

  3. Pokud chcete sestavit edici C# nebo Visual Basic .NET řešení, postupujte podle pokynů v části Sestavení ukázek windows Communication Foundation.

  4. Pokud chcete spustit ukázku v konfiguraci s jedním nebo více počítači, postupujte podle pokynů v části Spuštění ukázek windows Communication Foundation.

Ve výchozím nastavení NetMsmqBindingje povolené zabezpečení přenosu. Pro zabezpečení MsmqAuthenticationMode přenosu MSMQ existují dvě relevantní vlastnosti a MsmqProtectionLevel. Ve výchozím nastavení je režim ověřování nastavený Windows a úroveň ochrany je nastavena na Sign. Aby služba MSMQ poskytovala funkci ověřování a podepisování, musí být součástí domény a musí být nainstalovaná možnost integrace služby Active Directory pro MSMQ. Pokud tuto ukázku spustíte na počítači, který nesplňuje tato kritéria, zobrazí se chyba.

Spuštění ukázky na počítači připojeném k pracovní skupině nebo bez integrace služby Active Directory

  1. Pokud váš počítač není součástí domény nebo nemá nainstalovanou integraci služby Active Directory, vypněte zabezpečení přenosu nastavením režimu ověřování a úrovně ochrany tak, jak None je znázorněno v následujícím vzorovém konfiguračním kódu.

    <system.serviceModel>
      <services>
        <service name="Microsoft.ServiceModel.Samples.OrderProcessorService"
                 behaviorConfiguration="OrderProcessorServiceBehavior">
          <host>
            <baseAddresses>
              <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
            </baseAddresses>
          </host>
          <!-- Define NetMsmqEndpoint. -->
          <endpoint
              address="net.msmq://localhost/private/ServiceModelSamplesTransacted"
              binding="netMsmqBinding"
              bindingConfiguration="Binding1"
           contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
          <!-- 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="Binding1">
            <security mode="None" />
          </binding>
        </netMsmqBinding>
      </bindings>
    
        <behaviors>
          <serviceBehaviors>
            <behavior name="OrderProcessorServiceBehavior">
              <serviceMetadata httpGetEnabled="True"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
      </system.serviceModel>
    
  2. Před spuštěním ukázky nezapomeňte změnit konfiguraci na serveru i klientovi.

    Poznámka:

    Nastavení security mode , které None odpovídá nastavení MsmqAuthenticationMode, MsmqProtectionLevela Message zabezpečení pro None.