Two-Way Komunikasi

Sampel Two-Way menunjukkan cara melakukan komunikasi antrian dua jalur yang ditransaksikan melalui MSMQ. Sampel ini menggunakan pengikatan netMsmqBinding . Dalam hal ini, layanan ini adalah aplikasi konsol yang dihosting sendiri yang memungkinkan Anda memantau layanan yang menerima pesan antrean.

Nota

Prosedur penyiapan dan instruksi build untuk sampel ini terletak di akhir topik ini.

Sampel ini didasarkan pada Transacted MSMQ Binding.

Dalam komunikasi antrian, klien berkomunikasi dengan layanan menggunakan antrian. Klien mengirim pesan ke antrean, dan layanan menerima pesan dari antrean. Oleh karena itu, layanan dan klien tidak harus beroperasi pada saat yang bersamaan untuk berkomunikasi menggunakan antrean.

Contoh ini menunjukkan komunikasi dua arah menggunakan antrian. Klien mengirim pesanan pembelian ke antrean dari dalam cakupan transaksi. Layanan menerima dan memproses pesanan, kemudian menghubungi kembali klien dengan status pesanan dari antrean dalam konteks transaksi. Untuk memfasilitasi komunikasi dua arah, klien dan layanan menggunakan antrean untuk mengantrekan pesanan pembelian dan status pesanan.

Kontrak layanan IOrderProcessor mendefinisikan operasi-operasi satu arah yang cocok untuk penggunaan antrean. Operasi layanan mencakup titik akhir balasan yang akan digunakan untuk mengirim status pesanan. Titik akhir balasan adalah URI antrean untuk mengirim status pesanan kembali ke klien. Aplikasi pemrosesan pesanan mengimplementasikan kontrak ini.

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

Kontrak balasan untuk mengirim status pesanan ditentukan oleh klien. Klien menerapkan kontrak status pesanan. Layanan ini menggunakan proksi yang dihasilkan dari kontrak ini untuk mengirim status pesanan kembali ke klien.

[ServiceContract]
public interface IOrderStatus
{
    [OperationContract(IsOneWay = true)]
    void OrderStatus(string poNumber, string status);
}

Proses layanan memproses pesanan pembelian yang telah dikirimkan. OperationBehaviorAttribute diterapkan pada operasi layanan untuk menentukan pendaftaran otomatis dalam transaksi yang digunakan untuk menerima pesan dari antrean dan penyelesaian transaksi otomatis saat penyelesaian operasi layanan. Kelas Orders merangkum fungsionalitas pemrosesan pesanan. Dalam hal ini, sistem menambahkan pesanan pembelian ke kamus. Transaksi yang didaftarkan oleh operasi layanan tersedia untuk digunakan oleh operasi di kelas Orders.

Operasi layanan, selain memproses pesanan pembelian yang sudah diterima, membalas klien mengenai status pesanan.

[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SubmitPurchaseOrder(PurchaseOrder po, string reportOrderStatusTo)
{
    Orders.Add(po);
    Console.WriteLine("Processing {0} ", po);
    Console.WriteLine("Sending back order status information");
    NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding("ClientCallbackBinding");
    OrderStatusClient client = new OrderStatusClient(msmqCallbackBinding, new EndpointAddress(reportOrderStatusTo));

    // Please note that the same transaction that is used to dequeue the purchase order is used
    // to send back order status.
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    {
        client.OrderStatus(po.PONumber, po.Status);
        scope.Complete();
    }
    //Close the client.
    client.Close();
}

Nama antrean MSMQ ditentukan di bagian appSettings dari file konfigurasi. Titik akhir untuk layanan ditentukan di bagian System.ServiceModel dari file konfigurasi.

Nota

Nama antrean MSMQ dan alamat titik akhir menggunakan konvensi alamat yang sedikit berbeda. Nama antrean MSMQ menggunakan titik (.) untuk komputer lokal dan pemisah garis miring terbalik dalam jalurnya. Alamat titik akhir Windows Communication Foundation (WCF) menentukan skema net.msmq:, menggunakan "localhost" untuk komputer lokal, dan menggunakan garis miring di jalurnya. Untuk membaca dari antrean yang dihosting di komputer jarak jauh, ganti "." dan "localhost" dengan nama komputer jarak jauh tersebut.

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

// Host the service within this EXE console application.
public static void Main()
{
    // Get 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();
    }
}

Klien membuat transaksi. Komunikasi dengan antrian pesan terjadi dalam ruang lingkup transaksi, yang mengakibatkan diperlakukan sebagai unit atomik di mana semua pesan berhasil atau gagal.

// Create a ServiceHost for the OrderStatus service type.
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderStatusService)))
{

    // Open the ServiceHostBase to create listeners and start listening for order status messages.
    serviceHost.Open();

    // Create the purchase order.
    ...

    // Create a client with given client endpoint configuration.
    OrderProcessorClient client = new OrderProcessorClient("OrderProcessorEndpoint");

    //Create a transaction scope.
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    {
        string hostName = Dns.GetHostName();

        // Make a queued call to submit the purchase order.
        client.SubmitPurchaseOrder(po, "net.msmq://" + hostName + "/private/ServiceModelSamplesTwo-way/OrderStatus");

        // Complete the transaction.
        scope.Complete();
    }

    //Close down the client.
    client.Close();

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

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

Kode klien menerapkan IOrderStatus kontrak untuk menerima status pesanan dari layanan. Dalam hal ini, ia mencetak status pesanan.

[ServiceBehavior]
public class OrderStatusService : IOrderStatus
{
    [OperationBehavior(TransactionAutoComplete = true,
                        TransactionScopeRequired = true)]
    public void OrderStatus(string poNumber, string status)
    {
        Console.WriteLine("Status of order {0}:{1} ", poNumber ,
                                                           status);
    }
}

Antrean status pesanan dibuat dalam Main metode . Konfigurasi klien mencakup konfigurasi layanan status pesanan untuk menghosting layanan status pesanan, seperti yang ditunjukkan dalam konfigurasi sampel berikut.

<appSettings>
  <!-- Use appSetting to configure MSMQ queue name. -->
  <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderStatus" />
</appSettings>

<system.serviceModel>

  <services>
    <service
       name="Microsoft.ServiceModel.Samples.OrderStatusService">
      <!-- Define NetMsmqEndpoint -->
      <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderStatus"
                binding="netMsmqBinding"
                contract="Microsoft.ServiceModel.Samples.IOrderStatus" />
    </service>
  </services>

  <client>
    <!-- Define NetMsmqEndpoint -->
    <endpoint name="OrderProcessorEndpoint"
              address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor"
              binding="netMsmqBinding"
              contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
  </client>

</system.serviceModel>

Saat Anda menjalankan sampel, aktivitas klien dan layanan ditampilkan di jendela layanan dan konsol klien. Anda dapat melihat layanan menerima pesan dari klien. Tekan ENTER di setiap jendela konsol untuk mematikan layanan dan klien.

Layanan menampilkan informasi pesanan pembelian dan menunjukkan bahwa layanan tersebut mengirim kembali status pesanan ke antrean status pesanan.

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

Processing Purchase Order: 124a1f69-3699-4b16-9bcc-43147a8756fc
        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

Sending back order status information

Klien menampilkan informasi status pesanan yang dikirim oleh layanan.

Press <ENTER> to terminate client.
Status of order 124a1f69-3699-4b16-9bcc-43147a8756fc:Pending

Untuk menyiapkan, mengompilasi, dan menjalankan sampel

  1. Pastikan Anda telah melakukan Prosedur Penyiapan One-Time untuk Sampel Windows Communication Foundation.

  2. Untuk membangun solusi edisi C# atau Visual Basic .NET, ikuti instruksi di Membangun Sampel Windows Communication Foundation.

  3. Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, ikuti instruksi di Menjalankan Sampel Windows Communication Foundation.

    Nota

    Jika Anda menggunakan Svcutil.exe untuk meregenerasi konfigurasi untuk sampel ini, pastikan untuk memodifikasi nama titik akhir dalam konfigurasi klien agar sesuai dengan kode klien.

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, MSMQ harus menjadi bagian dari domain dan opsi integrasi direktori aktif untuk MSMQ harus diinstal. Jika Anda menjalankan sampel ini pada komputer yang tidak memenuhi kriteria ini, Anda menerima kesalahan.

Untuk menjalankan sampel di komputer yang bergabung ke grup kerja atau tanpa integrasi direktori aktif

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

    <configuration>
    
      <appSettings>
        <!-- Use appSetting to configure MSMQ queue name. -->
        <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderProcessor" />
      </appSettings>
    
      <system.serviceModel>
        <services>
          <service
              name="Microsoft.ServiceModel.Samples.OrderProcessorService">
            <!-- Define NetMsmqEndpoint -->
            <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor"
                      binding="netMsmqBinding"
                      bindingConfiguration="TransactedBinding"
                      contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
          </service>
        </services>
    
        <bindings>
          <netMsmqBinding>
            <binding name="TransactedBinding" >
             <security mode="None" />
            </binding>
          </netMsmqBinding>
        </bindings>
    
      </system.serviceModel>
    
    </configuration>
    
  2. Menonaktifkan keamanan untuk konfigurasi klien menghasilkan hal berikut:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <!-- Use appSetting to configure MSMQ queue name. -->
        <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderStatus" />
      </appSettings>
    
      <system.serviceModel>
    
        <services>
          <service
             name="Microsoft.ServiceModel.Samples.OrderStatusService">
            <!-- Define NetMsmqEndpoint -->
            <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderStatus"
                      binding="netMsmqBinding"
                      bindingConfiguration="TransactedBinding" contract="Microsoft.ServiceModel.Samples.IOrderStatus" />
          </service>
        </services>
    
        <client>
          <!-- Define NetMsmqEndpoint -->
          <endpoint name="OrderProcessorEndpoint"
                    address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor"
                    binding="netMsmqBinding"
                    bindingConfiguration="TransactedBinding"
                    contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
        </client>
    
        <bindings>
          <netMsmqBinding>
            <binding name="TransactedBinding" >
             <security mode="None" />
            </binding>
          </netMsmqBinding>
        </bindings>
    
      </system.serviceModel>
    
    </configuration>
    
  3. Layanan untuk sampel ini membuat pengikatan di OrderProcessorService. Tambahkan baris kode setelah pengikatan dibuat untuk mengatur mode keamanan ke None.

    NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();
    msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
    
  4. Pastikan Anda mengubah konfigurasi di server dan klien sebelum menjalankan sampel.

    Nota

    Pengaturan security mode ke None setara dengan pengaturan MsmqAuthenticationMode, MsmqProtectionLevel atau Message keamanan ke None.