Megosztás a következőn keresztül:


Two-Way kommunikáció

A Two-Way minta bemutatja, hogyan hajthat végre kétirányú üzenetsoros kommunikációt az MSMQ-n keresztül. Ez a minta a netMsmqBinding kötést használja. Ebben az esetben a szolgáltatás egy saját üzemeltetésű konzolalkalmazás, amely lehetővé teszi az üzenetsorba helyezett üzeneteket fogadó szolgáltatás megfigyelését.

Megjegyzés:

A minta telepítési eljárása és összeállítási utasításai a témakör végén találhatók.

Ez a minta a "Transacted MSMQ kötésen" alapul.

Az üzenetsoros kommunikáció során az ügyfél üzenetsor használatával kommunikál a szolgáltatással. Az ügyfél üzeneteket küld egy üzenetsorba, és a szolgáltatás üzeneteket fogad az üzenetsorból. A szolgáltatásnak és az ügyfélnek ezért nem kell egyszerre futnia ahhoz, hogy üzenetsor használatával kommunikáljon.

Ez a minta kétirányú kommunikációt mutat be üzenetsorok használatával. Az ügyfél beszerzési rendeléseket küld a várólistára tranzakció hatókörén belülről. A szolgáltatás fogadja a rendeléseket, feldolgozza a rendelést, majd visszahívja az ügyfelet a rendelés állapotával a tranzakció hatókörén belüli üzenetsorból. A kétirányú kommunikáció megkönnyítése érdekében az ügyfél és a szolgáltatás egyaránt üzenetsorokat használ a beszerzési rendelések és a megrendelések állapotának lekérdezéséhez.

A szolgáltatási szerződés IOrderProcessor egyirányú szolgáltatásműveleteket határoz meg, amelyek megfelelnek a sorba állítás használatának. A szolgáltatásművelet tartalmazza a rendelési állapotok elküldéséhez használandó válaszvégpontot. A válaszvégpont az üzenetsor URI-ja, amely visszaküldi a rendelés állapotát az ügyfélnek. A rendelésfeldolgozó alkalmazás implementálja ezt a szerződést.

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

A rendelési állapot elküldésére vonatkozó válaszszerződést az ügyfél adja meg. Az ügyfél végrehajtja a rendelésállapot-szerződést. A szolgáltatás a szerződés generált proxyjával küldi vissza a rendelés állapotát az ügyfélnek.

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

A szolgáltatásművelet feldolgozza a beküldött beszerzési rendelést. A OperationBehaviorAttribute rendszer a szolgáltatásműveletre alkalmazza az automatikus beléptetés megadására egy tranzakcióban, amely az üzenet üzenetsorból való fogadására és a tranzakciók automatikus befejezésére szolgál a szolgáltatásművelet befejezésekor. Az Orders osztály a rendelésfeldolgozási funkciókat foglalja magában. Ebben az esetben hozzáadja a vásárlási rendelést egy szótárhoz. Az a tranzakció, amelyben a szolgáltatásművelet szerepel, elérhető az Orders osztály műveletei számára.

A szolgáltatásművelet a beküldött megrendelés feldolgozása mellett a rendelés állapotára válaszol az ügyfélnek.

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

Az MSMQ-üzenetsor neve a konfigurációs fájl AppSettings szakaszában van megadva. A szolgáltatás végpontja a konfigurációs fájl System.ServiceModel szakaszában van definiálva.

Megjegyzés:

Az MSMQ-üzenetsor neve és végpontcíme némileg eltérő címzési konvenciókban szerepel. Az MSMQ-üzenetsor neve egy pont (.) karaktert használ a helyi géphez és a fordított perjelelválasztókhoz az elérési útjában. A Windows Communication Foundation (WCF) végpontcíme a net.msmq: sémát határozza meg, a helyi géphez a "localhost" nevet használja, és az elérési útvonalában előre mutató perjeleket alkalmaz. Ha a távoli gépen üzemeltetett üzenetsorból szeretne olvasni, helyettesítse a "." és a "localhost" szöveget a távoli gép nevével.

A szolgáltatás saját üzemeltetésű. Az MSMQ-átvitel használatakor a használt üzenetsort előre létre kell hozni. Ez manuálisan vagy kódon keresztül is elvégezhető. Ebben a mintában a szolgáltatás ellenőrzi az üzenetsor meglétét, és szükség esetén létrehozza azt. A sor nevét a konfigurációs fájlból olvassák be. Az alapcímet a ServiceModel Metadata Segédprogram (Svcutil.exe) használja a szolgáltatáshoz tartozó proxy létrehozásához.

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

Az ügyfél létrehoz egy tranzakciót. Az üzenetsorsal való kommunikáció a tranzakció hatókörén belül történik, ezért atomi egységként kell kezelni, ahol minden üzenet sikeres vagy sikertelen.

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

Az ügyfélkód megvalósítja a IOrderStatus szerződést, hogy megkapja a rendelés állapotát a szolgáltatástól. Ebben az esetben kinyomtatja a rendelés állapotát.

[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);
    }
}

A rendszer létrehozza a rendelési állapotsort a Main metódusban. Az ügyfélkonfiguráció tartalmazza a rendelésállapot-szolgáltatás konfigurációját a rendelésállapot-szolgáltatás üzemeltetéséhez, ahogyan az az alábbi mintakonfigurációban látható.

<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>

A minta futtatásakor az ügyfél- és szolgáltatástevékenységek a szolgáltatás és az ügyfélkonzol ablakaiban is megjelennek. Láthatja, hogy a szolgáltatás üzeneteket fogad az ügyféltől. A szolgáltatás és az ügyfél leállításához nyomja le az ENTER billentyűt az egyes konzolablakokban.

A szolgáltatás megjeleníti a vásárlási rendelés adatait, és jelzi, hogy a rendelés állapotát visszaküldi a rendelés állapotsorába.

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

Az ügyfél megjeleníti a szolgáltatás által küldött rendelési állapotadatokat.

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

A példa beállítása, elkészítése és futtatása

  1. Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták One-Time beállítási eljárását.

  2. A megoldás C# vagy Visual Basic .NET kiadásának létrehozásához kövesse Windows Communication Foundation-mintákcímű témakör utasításait.

  3. Ha a mintát egy vagy több gép közötti konfigurációban szeretné futtatni, kövesse A Windows Communication Foundation-minták futtatásacímű témakör utasításait.

    Megjegyzés:

    Ha a Svcutil.exe-t használja a minta konfigurációjának újragenerálásához, mindenképpen módosítsa az ügyfélkonfiguráció végpontneveit, hogy azok megfeleljenek az ügyfélkódnak.

Alapértelmezés szerint az NetMsmqBinding átviteli biztonsági engedélyezve van. Az MSMQ átviteli biztonságának két lényeges tulajdonsága van, MsmqAuthenticationMode és MsmqProtectionLevel. alapértelmezés szerint a hitelesítési mód be van állítva Windows , a védelmi szint pedig a következőre van állítva Sign. Ahhoz, hogy az MSMQ biztosítsa a hitelesítési és aláírási funkciót, egy tartománynak kell lennie, és telepítenie kell az MSMQ Active Directory-integrációs lehetőségét. Ha a mintát olyan számítógépen futtatja, amely nem felel meg ezeknek a feltételeknek, hibaüzenet jelenik meg.

A minta futtatása munkacsoporthoz csatlakoztatott számítógépen vagy Active Directory-integráció nélkül

  1. Ha a számítógép nem része tartománynak, vagy nincs telepítve active directory-integráció, kapcsolja ki az átviteli biztonságot úgy, hogy a hitelesítési módot és a védelmi szintet az alábbi mintakonfigurációban látható módon None állítja be:

    <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. Az ügyfélkonfiguráció biztonságának kikapcsolása a következőket hozza létre:

    <?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. A minta szolgáltatása létrehoz egy kötést a OrderProcessorService. Adjon hozzá egy kódsort a kötés példányosítása után a biztonsági mód beállításához None.

    NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();
    msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
    
  4. A minta futtatása előtt győződjön meg arról, hogy a kiszolgálón és az ügyfélen is módosítja a konfigurációt.

    Megjegyzés:

    A security mode beállítása egyenértékű a None, MsmqAuthenticationMode vagy MsmqProtectionLevel biztonsági beállítások Message értékre történő beállításával.