Bagikan melalui


Pengikatan MSMQ yang Ditransaksikan

Contoh yang ditransaksikan menunjukkan cara melakukan komunikasi antrean yang ditransaksikan menggunakan Message Queuing (MSMQ).

Catatan

Prosedur penyiapan dan petunjuk pembuatan untuk sampel ini terdapat di akhir topik ini.

Di komunikasi dalam antrean, klien berkomunikasi ke layanan menggunakan antrean. Lebih tepatnya, klien mengirim pesan ke antrean. Layanan menerima pesan dari antrean. Oleh karena itu, layanan dan klien tidak harus berjalan secara bersamaan untuk berkomunikasi menggunakan antrean.

Ketika transaksi digunakan untuk mengirim dan menerima pesan, sebenarnya ada dua transaksi terpisah. Ketika klien mengirim pesan dalam cakupan transaksi, transaksi bersifat lokal untuk klien dan manajer antrean klien. Ketika layanan menerima pesan dalam cakupan transaksi, transaksi bersifat lokal untuk layanan dan manajer antrean penerima. Sangat penting untuk diingat bahwa klien dan layanan tidak berpartisipasi dalam transaksi yang sama; sebaliknya, mereka menggunakan transaksi yang berbeda saat melakukan operasi mereka (seperti mengirim dan menerima) dengan antrean.

Dalam sampel ini, klien mengirim batch pesan ke layanan dari dalam cakupan transaksi. Pesan yang dikirim ke antrean kemudian diterima oleh layanan dalam cakupan transaksi yang ditentukan oleh layanan.

Kontrak layanan adalah IOrderProcessor, seperti yang ditunjukkan dalam kode sampel berikut. Antarmuka mendefinisikan layanan satu arah yang cocok untuk digunakan dengan antrean.

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

Perilaku layanan menentukan perilaku operasi dengan TransactionScopeRequired diatur ke true. Ini memastikan bahwa cakupan transaksi yang sama yang digunakan untuk mengambil pesan dari antrean digunakan oleh manajer sumber daya apa pun yang diakses oleh metode. Ini juga menjamin bahwa jika metode melempar pengecualian, pesan dikembalikan ke antrean. Tanpa mengatur perilaku operasi ini, saluran yang diantrekan membuat transaksi untuk membaca pesan dari antrean dan menerapkannya secara otomatis sebelum dikirim sehingga jika operasi gagal, pesan akan menghilang. Skenario yang paling umum adalah operasi layanan untuk mendaftarkan transaksi yang digunakan untuk membaca pesan dari antrean, seperti yang ditunjukkan dalam kode berikut.

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

Layanan ini dihost sendiri. Saat menggunakan transportasi MSMQ, antrean yang digunakan harus dibuat terlebih dahulu. Ini dapat dilakukan secara manual atau melalui kode. Dalam sampel ini, layanan berisi kode untuk memeriksa keberadaan antrean dan membuat antrean jika tidak ada. Nama antrean dibaca dari file konfigurasi. Alamat dasar digunakan oleh Alat Utilitas Metadata ServiceModel (Svcutil.exe) untuk menghasilkan proksi untuk layanan.

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

Nama antrean MSMQ ditentukan di bagian appSettings dari file konfigurasi, seperti yang ditunjukkan dalam konfigurasi sampel berikut.

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

Catatan

Nama antrean menggunakan titik (.) untuk mesin lokal dan pemisah garis miring terbalik di jalurnya saat membuat antrean menggunakan System.Messaging. Titik akhir Windows Communication Foundation (WCF) menggunakan alamat antrean dengan skema net.msmq, menggunakan "localhost" untuk menunjukkan mesin lokal, dan menggunakan garis miring di jalurnya.

Klien membuat cakupan transaksi. Komunikasi dengan antrean terjadi dalam cakupan transaksi, menyebabkannya diperlakukan sebagai unit atomik di mana semua pesan dikirim ke antrean atau tidak ada pesan yang dikirim ke antrean. Transaksi dilakukan dengan memanggil Complete pada cakupan transaksi.

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

Untuk memverifikasi bahwa transaksi berfungsi, ubah klien dengan mengomentari cakupan transaksi seperti yang ditunjukkan dalam kode sampel berikut, membangun kembali solusi, dan menjalankan klien.

//scope.Complete();

Karena transaksi tidak selesai, pesan tidak dikirim ke antrean.

Saat Anda menjalankan sampel, aktivitas klien dan layanan ditampilkan baik di jendela konsol layanan dan klien. Anda dapat melihat layanan menerima pesan dari klien. Tekan ENTER di setiap jendela konsol untuk mematikan layanan dan klien. Perhatikan bahwa karena antrean sedang digunakan, klien dan layanan tidak harus aktif dan dijalankan pada saat yang sama. Anda dapat menjalankan klien, mematikannya, dan kemudian memulai layanan dan masih menerima pesannya.

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

Untuk menyiapkan, membangun, dan menjalankan sampel

  1. Pastikan Anda telah melakukan Prosedur Penyiapan Satu Kali untuk Sampel Windows Communication Foundation.

  2. Jika layanan dijalankan terlebih dahulu, layanan akan memeriksa untuk memastikan bahwa antrean ada. Jika antrean tidak ada, layanan akan membuatnya. Anda dapat menjalankan layanan terlebih dahulu untuk membuat antrean, atau Anda dapat membuatnya melalui Pengelola Antrean MSMQ. Ikuti langkah-langkah ini untuk membuat antrean di Windows 2008.

    1. Buka Pengelola Server di Visual Studio 2012.

    2. Luaskan tab Fitur.

    3. Klik kanan Antrean Pesan Privat, dan pilih Baru, Antrean Privat.

    4. Centang kotak Transaksional.

    5. Masukkan ServiceModelSamplesTransacted sebagai nama antrean baru.

  3. Untuk membangun solusi edisi C# atau Visual Basic .NET, ikuti petunjuknya di Membangun Sampel WCF.

  4. Untuk menjalankan sampel dalam konfigurasi tunggal atau lintas komputer, ikuti petunjuk di Menjalankan Sampel Windows Communication Foundation.

Secara default dengan NetMsmqBinding, keamanan transportasi diaktifkan. Ada dua properti yang relevan untuk keamanan transportasi MSMQ, MsmqAuthenticationMode dan MsmqProtectionLevel. Secara default, mode autentikasi diatur ke Windows dan tingkat perlindungan diatur ke Sign. Agar MSMQ menyediakan fitur autentikasi dan penandatanganan, ini harus menjadi bagian dari domain dan opsi integrasi direktori aktif untuk MSMQ harus diinstal. Jika Anda menjalankan sampel ini di komputer yang tidak memenuhi kriteria ini, Anda akan menerima kesalahan.

Untuk menjalankan sampel di komputer yang digabungkan ke grup kerja atau tanpa integrasi Active Directory

  1. Jika komputer Anda bukan bagian dari domain atau tidak memiliki integrasi Active Directory yang terinstal, nonaktifkan keamanan transportasi dengan mengatur mode autentikasi dan tingkat perlindungan ke None seperti yang ditunjukkan dalam kode konfigurasi sampel berikut.

    <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. Pastikan Anda mengubah konfigurasi di server dan klien sebelum menjalankan sampel.

    Catatan

    Mengatur security mode ke None setara dengan mengatur keamanan MsmqAuthenticationMode, MsmqProtectionLevel, dan Message ke None.