Dela via


Transacted MSMQ-bindning

Exemplet Transacted visar hur du utför transacted queued communication med hjälp av Message Queuing (MSMQ).

Kommentar

Installationsproceduren och bygginstruktionerna för det här exemplet finns i slutet av det här avsnittet.

I kökommunikation kommunicerar klienten till tjänsten med hjälp av en kö. Mer exakt skickar klienten meddelanden till en kö. Tjänsten tar emot meddelanden från kön. Tjänsten och klienten behöver därför inte köras samtidigt för att kommunicera med en kö.

När transaktioner används för att skicka och ta emot meddelanden finns det faktiskt två separata transaktioner. När klienten skickar meddelanden inom omfånget för en transaktion är transaktionen lokal för klienten och klientköhanteraren. När tjänsten tar emot meddelanden inom transaktionens omfång är transaktionen lokal för tjänsten och den mottagande köhanteraren. Det är mycket viktigt att komma ihåg att klienten och tjänsten inte deltar i samma transaktion. I stället använder de olika transaktioner när de utför sina åtgärder (till exempel skicka och ta emot) med kön.

I det här exemplet skickar klienten en batch med meddelanden till tjänsten från en transaktions omfång. Meddelandena som skickas till kön tas sedan emot av tjänsten inom det transaktionsomfång som definieras av tjänsten.

Tjänstkontraktet är IOrderProcessor, som du ser i följande exempelkod. Gränssnittet definierar en enkelriktad tjänst som är lämplig för användning med köer.

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

Tjänstbeteendet definierar ett åtgärdsbeteende med TransactionScopeRequired inställt på true. Detta säkerställer att samma transaktionsomfång som används för att hämta meddelandet från kön används av alla resurshanterare som används av metoden. Det garanterar också att om metoden utlöser ett undantag returneras meddelandet till kön. Utan att ange det här åtgärdsbeteendet skapar en köad kanal en transaktion för att läsa meddelandet från kön och checkar in det automatiskt innan den skickas så att meddelandet går förlorat om åtgärden misslyckas. Det vanligaste scenariot är att tjänståtgärder registrerar i transaktionen som används för att läsa meddelandet från kön, vilket visas i följande kod.

 // 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);
     }
  …
}

Tjänsten är lokalt installerad. När du använder MSMQ-transporten måste den kö som används skapas i förväg. Detta kan göras manuellt eller via kod. I det här exemplet innehåller tjänsten kod för att kontrollera om kön finns och skapa kön om den inte finns. Könamnet läse från konfigurationsfilen. Basadressen används av ServiceModel Metadata Utility Tool (Svcutil.exe) för att generera proxyn till tjänsten.

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

MSMQ-könamnet anges i en app Inställningar avsnitt i konfigurationsfilen, enligt följande exempelkonfiguration.

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

Kommentar

Könamnet använder en punkt (.) för den lokala datorn och omvänt snedstrecksavgränsare i sökvägen när du skapar kön med .System.Messaging WCF-slutpunkten (Windows Communication Foundation) använder köadressen med net.msmq-schemat, använder "localhost" för att ange den lokala datorn och använder snedstreck i sin sökväg.

Klienten skapar ett transaktionsomfång. Kommunikation med kön sker inom transaktionens omfång, vilket gör att den behandlas som en atomisk enhet där alla meddelanden skickas till kön eller inget av meddelandena skickas till kön. Transaktionen genomförs genom att anropa Complete transaktionsomfånget.

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

Kontrollera att transaktioner fungerar genom att ändra klienten genom att kommentera transaktionsomfånget enligt följande exempelkod, återskapa lösningen och köra klienten.

//scope.Complete();

Eftersom transaktionen inte har slutförts skickas inte meddelandena till kön.

När du kör exemplet visas klient- och tjänstaktiviteterna i både tjänst- och klientkonsolfönstren. Du kan se att tjänsten tar emot meddelanden från klienten. Tryck på RETUR i varje konsolfönster för att stänga av tjänsten och klienten. Observera att eftersom köer används behöver klienten och tjänsten inte vara igång samtidigt. Du kan köra klienten, stänga av den och sedan starta tjänsten och fortfarande ta emot meddelandena.

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

Så här konfigurerar du, skapar och kör exemplet

  1. Kontrollera att du har utfört engångsinstallationsproceduren för Windows Communication Foundation-exempel.

  2. Om tjänsten körs först kontrollerar den att kön finns. Om kön inte finns skapar tjänsten en. Du kan köra tjänsten först för att skapa kön, eller så kan du skapa en via MSMQ Queue Manager. Följ de här stegen för att skapa en kö i Windows 2008.

    1. Öppna Serverhanteraren i Visual Studio 2012.

    2. Expandera fliken Funktioner .

    3. Högerklicka på Privata meddelandeköer och välj Ny privat .

    4. Markera rutan Transaktionell .

    5. Ange ServiceModelSamplesTransacted som namnet på den nya kön.

  3. Om du vill skapa C# eller Visual Basic .NET-versionen av lösningen följer du anvisningarna i Skapa Windows Communication Foundation-exempel.

  4. Om du vill köra exemplet i en konfiguration med en eller flera datorer följer du anvisningarna i Köra Windows Communication Foundation-exempel.

Som standard NetMsmqBindingär transportsäkerheten aktiverad. Det finns två relevanta egenskaper för MSMQ-transportsäkerhet MsmqAuthenticationMode och MsmqProtectionLevel. Som standard är autentiseringsläget inställt på Windows och skyddsnivån är inställd på Sign. För att MSMQ ska kunna tillhandahålla autentiserings- och signeringsfunktionen måste den vara en del av en domän och Active Directory-integreringsalternativet för MSMQ måste vara installerat. Om du kör det här exemplet på en dator som inte uppfyller dessa kriterier får du ett fel.

Så här kör du exemplet på en dator som är ansluten till en arbetsgrupp eller utan Active Directory-integrering

  1. Om datorn inte är en del av en domän eller inte har Active Directory-integrering installerad inaktiverar du transportsäkerheten genom att ställa in autentiseringsläget och skyddsnivån på None enligt följande exempelkonfigurationskod.

    <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. Se till att du ändrar konfigurationen på både servern och klienten innan du kör exemplet.

    Kommentar

    Inställningen security mode till None motsvarar inställningen MsmqAuthenticationMode, MsmqProtectionLeveloch Message säkerhet till None.