Compartir a través de


Activación MSMQ

Download sample

Este ejemplo muestra cómo hospedar aplicaciones en el servicio de activación del proceso de Windows (WAS) que se lee en una cola de mensajes. Este ejemplo utiliza netMsmqBinding y está basado en el ejemplo Comunicación bidireccional. El servicio en este caso es una aplicación hospedada en Web y el cliente está auto-hospedado y proporciona resultados a la consola para observar el estado de pedidos de compra enviados.

Nota

El procedimiento de instalación y las instrucciones de compilación de este ejemplo se encuentran al final de este tema.

Windows Process Activation Service (WAS), el nuevo mecanismo de activación de proceso para Windows Server 2008, proporciona características similares a IIS que previamente sólo estaban disponibles en aplicaciones basadas en HTTP a aplicaciones que utilizan protocolos no http. Windows Communication Foundation (WCF) utiliza la interfaz de Listener Adapter para comunicar las peticiones de activación que se reciben a través de los protocolos no http admitidas por WCF, como TCP, canalizaciones con nombre y MSMQ. La funcionalidad para recibir solicitudes a través de protocolos no http está hospedada por servicios de Windows administrados que se ejecutan en SMSvcHost.exe.

El servicio Net.Msmq Listener Adapter (NetMsmqActivator) activa aplicaciones en cola basadas en mensajes en la cola.

El cliente envía los pedidos de compra al servicio desde dentro del ámbito de una transacción. El servicio recibe las órdenes en una transacción y las procesa. El servicio llama a continuación de nuevo al cliente con el estado del orden. Para facilitar la comunicación bidireccional, tanto el cliente como el servicio utilizan las colas para poner en cola los pedidos de compra y el estado de la orden.

El contrato de servicios IOrderProcessor define operaciones de servicio unidireccionales que satisfacen el uso de poner en cola. La operación del servicio utiliza el extremo de respuesta para enviar estados de orden al cliente. La dirección de extremo de la respuesta es el URI de la cola utilizado para devolver el estado del orden al cliente. La aplicación de procesamiento de orden implementa este contrato.

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

El cliente especifica el contrato de la respuesta para enviar el estado de la orden. El cliente implementa el contrato del estado de la orden. El servicio utiliza el cliente generado de este contrato para devolver el estado de la orden al cliente.

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

La operación del servicio procesa el pedido de compra enviado. OperationBehaviorAttribute se aplica a la operación del servicio para especificar la inscripción automática en la transacción que se utiliza para recibir el mensaje de la cola y la realización automática de la transacción en la realización de la operación del servicio. La clase Orders encapsula la funcionalidad del procesamiento de la orden. En este caso, agrega el pedido de compra a un diccionario. La transacción en la que la operación del servicio se dio de alta está disponible para las operaciones en la clase Orders.

La operación del servicio, además de procesar el pedido de compra enviado, responde de nuevo al cliente acerca del estado de la orden.

public class OrderProcessorService : IOrderProcessor
{
    [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();
        msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
        OrderStatusClient client = new OrderStatusClient(msmqCallbackBinding, new EndpointAddress(reportOrderStatusTo));
        // please note that the same transaction that is used to dequeue purchase order is used
        // to send back order status
        using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
        {
            client.OrderStatus(po.PONumber, po.Status);
            scope.Complete();
        }
    }

El enlace de cliente que se ha de utilizar se especifica utilizando un archivo de configuración.

El nombre de cola de MSMQ se especifica en una sección appSettings del archivo de configuración. El extremo para el servicio se define en la sección de System.ServiceModel del archivo de configuración.

Nota

El nombre de cola de MSMQ y la dirección de extremo utilizan convenciones de direccionamiento ligeramente diferentes. El nombre de la cola MSMQ utiliza un punto (.) para el equipo local y separadores con barra diagonal inversa en su ruta. La dirección de extremo WCF especifica net.msmq: el esquema utiliza el "host local" para el equipo local y utiliza barras diagonales en su ruta de acceso. Para leer de una cola que se hospeda en el equipo remoto, reemplace el "." y el “host local” por el nombre del equipo remoto.

Un archivo .svc con el nombre de la clase se utiliza para hospedar el código del servicio en WAS.

El propio archivo Service.svc contiene una directiva para crear OrderProcessorService:

<%@ServiceHost language="c#" Debug="true" Service="Microsoft.ServiceModel.Samples.OrderProcessorService"%>

El archivo Service.svc también contiene una directiva de ensamblado para asegurar que se carga System.Transactions.dll:

<%@Assembly name="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"%>

El cliente crea un ámbito de transacción. La comunicación con el servicio tiene lugar dentro del ámbito de la transacción, produciendo que se trate como una unidad atómica donde todos los mensajes tienen éxito o dan error. La transacción se confirma llamando a Complete en el ámbito de la transacción:

using (ServiceHost serviceHost = new ServiceHost(typeof(OrderStatusService)))
{
    // Open the ServiceHostBase to create listeners and start listening 
    // for order status messages.
    serviceHost.Open();

    // Create a proxy with given client endpoint configuration
    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, 
       "net.msmq://localhost/private/ServiceModelSamples/OrderStatus");
        // 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();

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

El código de cliente implementa el contratoIOrderStatus para recibir el estado de la orden del servicio. En este caso, imprime el estado de la orden.

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

La cola de estado de la orden se crea en el método Main. La configuración del cliente incluye la configuración del servicio del estado de la orden para hospedar el servicio del estado de la orden, tal y como se muestra en la configuración del ejemplo siguiente:

<appSettings>
    <!-- use appSetting to configure MSMQ queue name -->
    <add key="targetQueueName" value=".\private$\ServiceModelSamples/service.svc" />
    <add key="responseQueueName" value=".\private$\ServiceModelSamples/OrderStatus" />
  </appSettings>

<system.serviceModel>

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

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

  </system.serviceModel>

Al ejecutar el ejemplo, las actividades del servicio y del cliente se muestran en las ventanas de la consola del cliente y del servidor. Puede ver que el servidor recibe mensajes desde el cliente. Presione Entrar en cada ventana de la consola para cerrar el servidor y el cliente.

El cliente muestra la información del estado de la orden enviada por el servidor.

Press <ENTER> to terminate client.
Status of order 70cf9d63-3dfa-4e69-81c2-23aa4478ebed :Pending

Para configurar, generar y ejecutar el ejemplo

  1. Asegúrese de que ha realizado el Procedimiento de instalación único para ejemplos de Windows Communication Foundation. Además, debe instalar los componentes de activación no HTTPWCF:

    1. En el menú Inicio, elija Panel de control.

    2. Seleccione Programas y características.

    3. Haga clic en Activar o desactivar los componentes Windows.

    4. En Resumen de Características, haga clic en Añadir características.

    5. Expanda el nodo Activación WCF.

    6. Expanda el nodo Microsoft .NET Framework 3.0 y compruebe la característica Activación No HTTP de Windows Communication Foundation .

  2. Para generar el código C# o Visual Basic .NET Edition de la solución, siga las instrucciones de Generación de ejemplos de Windows Communication Foundation.

  3. Ejecute el cliente ejecutando client.exe de una ventana de comandos. Esto crea la cola y envía un mensaje a la misma. Deje que el cliente se ejecute para ver el resultado del servicio que lee el mensaje

  4. El servicio de activación MSMQ se ejecuta como servicio de red de manera predeterminada. Por consiguiente, la cola que se utiliza para activar la aplicación debe tener permisos de recepción y lectura para el Servicio de la Red. Esto se puede agregar utilizando el MMC de cola de mensajes:

    1. En el menú Inicio, haga clic en Ejecutar, a continuación, escriba Compmgmt.msc y presione Entrar.

    2. En Servicios y Aplicaciones, expanda Cola de mensajes.

    3. Haga clic en Colas privadas.

    4. Haga clic con el botón derecho en la cola (servicemodelsamples/Service.svc) y elija Propiedades.

    5. En la pestaña de Seguridad, haga clic en Agregar y proporcione permisos de recepción y lectura al Servicio de la Red.

  5. Configure el Windows Process Activation Service (WAS) para admitir la activación de MSMQ.

    1. Ejecute Inetmgr.exe.

    2. Para permitir al sitio web predeterminado comunicarse a través del protocolo net.msmq, debe agregar un nuevo enlace del sitio. El archivo de comandos AddMsmqSiteBinding.cmd está incluido en el directorio de ejemplos para esto.

  6. Si no lo ha hecho previamente, asegúrese de que el servicio de activación MSMQ está habilitado. En el menú Inicio , haga clic en Ejecutar, y escriba Services.msc. Busque Net.Msmq Listener Adapteren la lista de servicios. Haga clic con el botón derecho del ratón y seleccione Propiedades. Establezca el Tipo de inicio en Automático, haga clic en Aplicar y haga clic en el botón deInicio. Este paso sólo necesita ser realizado una vez antes del primer uso del servicio Net.Msmq Listener Adapter.

  7. Para ejecutar el ejemplo en una configuración con un único equipo o con varios, siga las instrucciones de Ejecución de ejemplos de Windows Communication Foundation. Adicionalmente, cambie el código en el cliente que envía el pedido de compra para reflejar el nombre de equipo en el URI de la cola al enviar el pedido de compra. Utilice el código siguiente:

client.SubmitPurchaseOrder(po, "net.msmq://localhost/private/ServiceModelSamples/OrderStatus");

De forma predeterminada, con el transporte de enlace netMsmqBinding, la seguridad está habilitada. Dos propiedades, MsmqAuthenticationMode y MsmqProtectionLevel, determinan juntas el tipo de seguridad de transporte. De manera predeterminada, el modo de autenticación está definido en Windows y el nivel de protección está definido en Sign. Para que MSMQ proporcione la característica de autenticación y firma, debe formar parte de un dominio. Si ejecuta este ejemplo en un equipo que no forma parte de un dominio, recibirá el error siguiente: "No existe el certificado de Message Queue Server interno del usuario".

Para ejecutar el ejemplo en un equipo unido a un grupo de trabajo

  1. Si su equipo no forma parte de un dominio, desactive la seguridad de transporte estableciendo el modo de autenticación y el nivel de protección en cero, tal y como se muestra en la configuración de ejemplo siguiente:

    <bindings>
        <netMsmqBinding>
            <binding configurationName="TransactedBinding">
                <security mode="None"/>
            </binding>
        </netMsmqBinding>
    </bindings>
    
  2. Cambie la configuración en el servidor y el cliente antes de ejecutar el ejemplo.

    Nota

    Establecer security mode en None es equivalente a definir MsmqAuthenticationMode, MsmqProtectionLevel y la seguridad de Message en None.

  3. Para habilitar la activación en un equipo combinado a un grupo de trabajo, el servicio de activación y el proceso de trabajador se deben ejecutar con una cuenta de usuario concreta (debe ser la misma para ambos) y la cola debe tener ACL para la cuenta de usuario concreta.

    Para cambiar la identidad bajo la que el proceso de trabajador se ejecuta:

    1. Ejecute Inetmgr.exe.

    2. En Grupos de aplicaciones, haga clic con el botón derecho enAppPool (normalmente DefaultAppPool) y elija Establecer valores predeterminados del grupo de aplicaciones.

    3. Cambie las propiedades Identity para utilizar la cuenta de usuario concreta.

    Para cambiar la identidad bajo la que el Servicio de Activación se ejecuta:

    1. Ejecute Services.msc.

    2. Haga clic con el botón derecho en Net.MsmqListener Adaptery elija Propiedades.

  4. Cambie la cuenta en la pestaña Inicio de sesión.

  5. En grupo de trabajo, el servicio se debe ejecutar también utilizando un token sin restricciones. Para ello, ejecute en una ventana de comandos lo siguiente:

    sc sidtype netmsmqactivator unrestricted
    

Footer image

Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.