Sdílet prostřednictvím


Obousměrná komunikace

Dvoucestná ukázka ukazuje, jak provést transactovanou obousměrnou komunikaci ve frontě přes MSMQ. Tato ukázka používá netMsmqBinding vazbu. V tomto případě je služba konzolovou aplikací v místním prostředí, která umožňuje sledovat službu, která přijímá zprávy ve frontě.

Poznámka:

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

Tato ukázka je založená na transactované vazbě MSMQ.

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

Tato ukázka ukazuje 2cestnou komunikaci pomocí front. Klient odešle nákupní objednávky do fronty z rozsahu transakce. Služba obdrží objednávky, zpracuje objednávku a potom zavolá klienta se stavem objednávky z fronty v rámci rozsahu transakce. Pro usnadnění obousměrné komunikace klient a služba používají fronty k zařazení nákupních objednávek a stavu objednávky.

Kontrakt IOrderProcessor služby definuje jednosměrné operace služby, které vyhovují použití front. Operace služby zahrnuje koncový bod odpovědi, který se má použít k odeslání stavu objednávky. Koncový bod odpovědi je identifikátor URI fronty pro odeslání stavu objednávky zpět klientovi. Aplikace pro zpracování objednávek implementuje tento kontrakt.

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

Klient určí kontrakt odpovědi na odeslání objednávky. Klient implementuje kontrakt stavu objednávky. Služba používá vygenerovaný proxy server tohoto kontraktu k odeslání stavu objednávky zpět klientovi.

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

Operace služby zpracuje odeslanou nákupní objednávku. Použije OperationBehaviorAttribute se na operaci služby k určení automatického zařazení v transakci, která se používá k přijetí zprávy z fronty a automatické dokončování transakcí při dokončení operace služby. Třída Orders zapouzdřuje funkce zpracování objednávek. V tomto případě přidá nákupní objednávku do slovníku. Transakce, ve které je operace služby zařazena, je k dispozici pro operace ve Orders třídě.

Operace služby kromě zpracování odeslané nákupní objednávky odpoví klientovi na stav objednávky.

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

Název fronty MSMQ se zadává v části aplikace Nastavení konfiguračního souboru. Koncový bod pro službu je definován v části System.ServiceModel konfiguračního souboru.

Poznámka:

Název fronty MSMQ a adresa koncového bodu používají mírně odlišné konvence adresování. Název fronty MSMQ používá tečku (.) pro místní počítač a oddělovače zpětného lomítka v jeho cestě. Adresa koncového bodu Wcf (Windows Communication Foundation) určuje net.msmq: scheme, používá pro místní počítač "localhost" a v cestě používá lomítka. Pokud chcete číst z fronty hostované na vzdáleném počítači, nahraďte ". a "localhost" názvem vzdáleného počítače.

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 služba zkontroluje existenci fronty a v případě potřeby ji vytvoří. 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 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();
    }
}

Klient vytvoří transakci. Komunikace s frontou probíhá v rámci transakce, což způsobuje, že se bude považovat za atomické jednotky, kde všechny zprávy proběhnou úspěšně nebo selžou.

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

Klientský kód implementuje IOrderStatus kontrakt pro příjem stavu objednávky ze služby. V tomto případě vytiskne stav objednávky.

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

Fronta stavu objednávky se vytvoří v Main metodě. Konfigurace klienta zahrnuje konfiguraci služby stavu objednávky pro hostování služby stavu objednávky, jak je znázorněno v následující ukázkové konfiguraci.

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

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.

Služba zobrazí informace o nákupní objednávce a indikuje, že odesílá zpět stav objednávky do fronty stavu objednávky.

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

Klient zobrazí informace o stavu objednávky odeslané službou.

Press <ENTER> to terminate client.
Status of order 124a1f69-3699-4b16-9bcc-43147a8756fc: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 chcete sestavit edici C# nebo Visual Basic .NET řešení, postupujte podle pokynů v části Sestavení ukázek windows Communication Foundation.

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

    Poznámka:

    Pokud použijete Svcutil.exe k opětovnému vygenerování konfigurace pro tuto ukázku, nezapomeňte upravit názvy koncových bodů v konfiguraci klienta tak, aby odpovídaly kódu klienta.

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 na úroveň Signochrany . 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í ukázkové konfiguraci:

    <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. Vypnutí zabezpečení pro konfiguraci klienta vygeneruje následující:

    <?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. Služba pro tuto ukázku vytvoří vazbu v objektu OrderProcessorService. Přidejte řádek kódu po vytvoření vazby pro nastavení režimu zabezpečení na None.

    NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();
    msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
    
  4. 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, MsmqProtectionLevel nebo Message zabezpečení Nonepro .