Condividi tramite


Procedura: scambiare messaggi con endpoint WCF e con applicazioni del sistema di accodamento dei messaggi

Per integrare le applicazioni esistenti del sistema di accodamento dei messaggi (MSMQ) con le applicazioni di Windows Communication Foundation (WCF) è possibile utilizzare l'associazione di integrazione con MSMQ per convertire i messaggi MSMQ in messaggi WCF e viceversa. Ciò consente di chiamare applicazioni MSMQ riceventi tramite un client WCF nonché chiamare servizi WCF tramite applicazioni MSMQ mittenti.

In questa sezione viene descritto come utilizzare l'associazione MsmqIntegrationBinding per la comunicazione in coda tra (1) un client WCF e un'applicazione MSMQ server scritta utilizzando System.Messaging e (2) un'applicazione MSMQ client e un servizio WCF.

Per un esempio completo in cui viene illustrato come chiamare un'applicazione MSMQ ricevente da un client WCF, vedere l'esempio Da Windows Communication Foundation a Accodamento messaggi.

Per un esempio completo in cui viene illustrato come chiamare un servizio WCF da un client MSMQ, vedere l'esempio Accodamento messaggi in Windows Communication Foundation.

Per creare un servizio WCF che riceve messaggi da un client MSMQ

  1. Creare un'interfaccia che definisca il contratto del servizio WCF che riceve messaggi in coda da un'applicazione MSMQ mittente, come illustrato nell'esempio di codice seguente.

    <ServiceContract(Namespace:="http:'Microsoft.ServiceModel.Samples")> _
    <ServiceKnownType(GetType(PurchaseOrder))> _
    Public Interface IOrderProcessor
        <OperationContract(IsOneWay:=True, Action:="*")> _
        Sub SubmitPurchaseOrder(ByVal msg As MsmqMessage(Of PurchaseOrder))
    End Interface
    
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    [ServiceKnownType(typeof(PurchaseOrder))]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
    }
    
  2. Implementare l'interfaccia e applicare l'attributo ServiceBehaviorAttribute alla classe, come mostrato nell'esempio di codice seguente.

    Public Class OrderProcessorService
        Implements IOrderProcessor
    
        <OperationBehavior(TransactionScopeRequired:=True, TransactionAutoComplete:=True)> _
        Public Sub SubmitPurchaseOrder(ByVal ordermsg As MsmqMessage(Of PurchaseOrder)) Implements IOrderProcessor.SubmitPurchaseOrder
            Dim po As PurchaseOrder = ordermsg.Body
            Dim statusIndexer As New Random()
            po.Status = statusIndexer.Next(3)
            Console.WriteLine("Processing {0} ", po)
        End Sub
    End Class
    
    public class OrderProcessorService : IOrderProcessor
    {
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> ordermsg)
        {
            PurchaseOrder po = (PurchaseOrder)ordermsg.Body;
            Random statusIndexer = new Random();
            po.Status = (OrderStates)statusIndexer.Next(3);
            Console.WriteLine("Processing {0} ", po);
        }
    
        // Host the service within this EXE console application.
    public static void Main()
    {
        // Get base address from appsettings in configuration.
        Uri baseAddress = new Uri(ConfigurationManager.AppSettings["baseAddress"]);
    
        // Create a ServiceHost for the CalculatorService type and provide the base address.
        using (ServiceHost serviceHost = new ServiceHost(typeof(IOrderProcessor), baseAddress))
        {
        // Open the ServiceHostBase to create listeners and start listening for messages.
            serviceHost.Open();
    
        // The service can now be accessed.
            Console.WriteLine("The service is ready.");
            Console.WriteLine("The service is running in the following account: {0}", WindowsIdentity.GetCurrent().Name);
            Console.WriteLine("Press <ENTER> to terminate service.");
            Console.WriteLine();
            Console.ReadLine();
    
        // Close the ServiceHostBase to shutdown the service.
            serviceHost.Close();
        }
    }
    
    }
    
  3. Creare un file di configurazione che specifica l'associazione MsmqIntegrationBinding.

    <configuration>
      <appSettings>
        <!-- use appSetting to configure MSMQ queue name -->
        <add key="orderQueueName" value=".\private$\Orders" />
        <add key="baseAddress" value="https://localhost:8000/ServiceModelSamples/Service" />
      </appSettings>
      <system.serviceModel>
        <services>
          <service 
            name="Microsoft.ServiceModel.Samples.OrderProcessorService" >
            <endpoint address="msmq.formatname:DIRECT=OS:.\private$\Orders"
                                    binding="msmqIntegrationBinding"
                      bindingConfiguration="OrderProcessorBinding" 
                      contract="Microsoft.ServiceModel.Samples.IOrderProcessor">
            </endpoint>
          </service>
        </services>
    
        <bindings>
          <msmqIntegrationBinding>
            <binding name="OrderProcessorBinding" >
              <security mode="None" />
            </binding>
          </msmqIntegrationBinding>
        </bindings>
    
      </system.serviceModel >
    
    </configuration>
    
  4. Creare un'istanza di un oggetto ServiceHost che utilizza l'associazione configurata.

Per creare un client WCF che invia messaggi a un'applicazione MSMQ ricevente

  1. Creare un'interfaccia che definisca il contratto di servizio del client WCF che invii messaggi in coda a un'applicazione MSMQ ricevente, come illustrato nell'esempio di codice seguente.

    <System.ServiceModel.ServiceContractAttribute(Namespace:="http:'Microsoft.ServiceModel.Samples")> _
    Public Interface IOrderProcessor
        <OperationContract(IsOneWay:=True, Action:="*")> _
        Sub SubmitPurchaseOrder(ByVal msg As MsmqMessage(Of PurchaseOrder))
    end interface
    
    Public Interface IOrderProcessorChannel
        Inherits IOrderProcessor, System.ServiceModel.IClientChannel
    End Interface
    
    [System.ServiceModel.ServiceContractAttribute(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
    }
    
    public interface IOrderProcessorChannel : IOrderProcessor, System.ServiceModel.IClientChannel
    {
    }
    
  2. Definire una classe client che verrà utilizzata dal client WCF per chiamare l'applicazione MSMQ ricevente.

    Dim binding As New MsmqIntegrationBinding()
    Dim address As New EndpointAddress("msmq.formatname:DIRECT=OS:.\\private$\\Orders")
    Dim channelFactory As New ChannelFactory(Of IOrderProcessor)(binding, address)
    Dim channel As IOrderProcessor = channelFactory.CreateChannel()
    
    Dim po As New PurchaseOrder()
    po.customerId = "somecustomer.com"
    po.poNumber = Guid.NewGuid().ToString()
    
    Dim lineItem1 As New PurchaseOrderLineItem()
    lineItem1.productId = "Blue Widget"
    lineItem1.quantity = 54
    lineItem1.unitCost = 29.99F
    
    Dim lineItem2 = New PurchaseOrderLineItem()
    lineItem2.productId = "Red Widget"
    lineItem2.quantity = 890
    lineItem2.unitCost = 45.89F
    
    Dim lineItems(2) As PurchaseOrderLineItem
    lineItems(0) = lineItem1
    lineItems(1) = lineItem2
    
    po.orderLineItems = lineItems
    
    Dim ordermsg As MsmqMessage(Of PurchaseOrder) = New MsmqMessage(Of PurchaseOrder)(po)
    Using scope As New TransactionScope(TransactionScopeOption.Required)
        channel.SubmitPurchaseOrder(ordermsg)
        scope.Complete()
    End Using
    Console.WriteLine("Order has been submitted:{0}", po)
    
    MsmqIntegrationBinding binding = new MsmqIntegrationBinding();
    EndpointAddress address = new EndpointAddress("msmq.formatname:DIRECT=OS:.\\private$\\Orders");
    ChannelFactory<IOrderProcessor> channelFactory = new ChannelFactory<IOrderProcessor>(binding, address);
    IOrderProcessor channel = channelFactory.CreateChannel();
    
    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;
    
    
    MsmqMessage<PurchaseOrder> ordermsg = new MsmqMessage<PurchaseOrder>(po);
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    {
        channel.SubmitPurchaseOrder(ordermsg);
        scope.Complete();
    }
    Console.WriteLine("Order has been submitted:{0}", po);
    
  3. Creare una configurazione che specifichi l'utilizzo dell'associazione MsmqIntegrationBinding.

    Dim binding As New MsmqIntegrationBinding("MyBindingConfig")
    
    MsmqIntegrationBinding binding = new MsmqIntegrationBinding("MyBindingConfig");
    
    <configuration>
        <system.serviceModel>
    
        <client>
          <endpoint  name="OrderResponseEndpoint" 
                    address="msmq.formatname:DIRECT=OS:.\private$\Orders"
                    binding="msmqIntegrationBinding"
                    bindingConfiguration="OrderProcessorBinding" 
                    contract="Microsoft.ServiceModel.Samples.IOrderProcessor">
          </endpoint>
        </client>
    
        <bindings>
          <msmqIntegrationBinding>
            <binding name="OrderProcessorBinding" >
              <security mode="None" />
            </binding>
          </msmqIntegrationBinding>
        </bindings>
    
      </system.serviceModel>
    
    </configuration>
    
  4. Creare un'istanza della classe client e chiamare il metodo definito dal servizio che riceve i messaggi.

    // 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;
    
    OrderProcessorClient client = new OrderProcessorClient("OrderResponseEndpoint");
    MsmqMessage<PurchaseOrder> ordermsg = new MsmqMessage<PurchaseOrder>(po);
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    {
        client.SubmitPurchaseOrder(ordermsg);
        scope.Complete();
    }
    
    Console.WriteLine("Order has been submitted:{0}", po);
    
    //Closing the client gracefully closes the connection and cleans up resources.
    client.Close();
    
    Console.WriteLine();
    Console.WriteLine("Press <ENTER> to terminate client.");
    Console.ReadLine();
    

Vedere anche

Attività

Procedura: scambiare messaggi in coda con endpoint WCF
Da Windows Communication Foundation a Accodamento messaggi
Accodamento messaggi in Windows Communication Foundation
Sicurezza dei messaggi nell'accodamento messaggi

Concetti

Panoramica delle code
Installazione accodamento messaggi (MSMQ)

Altre risorse

Message Queuing Integration Binding Samples