Partager via


MSMQ Activation

Cet exemple illustre comment héberger des applications dans le service d'activation de processus de Windows (Windows Process Activation Service, WAS) lues à partir d'une file d'attente de messages. Cet exemple, qui utilise la liaison netMsmqBinding, est basé sur l'exemple Two-Way Communication. Dans cet exemple, le service est une application hébergée par le Web et le client est auto-hébergé. Les résultats, qui s'affichent sur la console, permettent d'observer le statut des bons de commande envoyés.

ms752246.note(fr-fr,VS.90).gifRemarque :
La procédure d'installation ainsi que les instructions de génération relatives à cet exemple figurent en fin de rubrique.

Le service WAS, c'est-à-dire le nouveau mécanisme d'activation de processus pour Windows Server 2008, offre des fonctionnalités IIS désormais disponibles avec des applications non HTTP (auparavant disponibles uniquement avec des applications HTTP). Windows Communication Foundation (WCF) utilise l'interface d'adaptateur de l'écouteur pour transmettre les demandes d'activation reçues sur les protocoles non-HTTP pris en charge par WCF, tels que TCP, les canaux nommés et MSMQ. Les fonctionnalités de réception des demandes sur les protocoles non-HTTP sont hébergées par les services Windows managés qui s'exécutent dans SMSvcHost.exe.

Le service d'adaptateur (NetMsmqActivator) de l'écouteur Net.Msmq active les applications en file d'attente en fonction des messages figurant dans cette file.

Le client envoie des bons de commande au service dans les limites de l'étendue d'une transaction. Le service traite les bons de commande qu'il reçoit via cette transaction. Le service rappelle ensuite le client en utilisant l'état des bons de commande. Pour faciliter la communication bidirectionnelle, le client et service utilisent tous deux des files d'attente pour y placer les bons de commande et leur état.

Le contrat de service IOrderProcessor définit des opérations de service unidirectionnelles compatibles avec les files d'attente. L'opération de service utilise le point de terminaison de réponse pour envoyer les états de bon de commande au client. L'adresse du point de terminaison de réponse correspond à l'URI de la file d'attente utilisée pour renvoyer l'état des bons de commande au client. L'application de traitement des bons de commande implémente ce contrat.

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

Le contrat de réponse auquel envoyer l'état des bons de commande est spécifié par le client. Le client implémente le contrat d'état des bons de commande. Le service utilise le client généré de ce contrat pour renvoyer l'état des bons de commande au client.

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

L'opération de service traite le bon de commande envoyé. L'attribut OperationBehaviorAttribute est appliqué à l'opération de service pour indiquer l'inscription automatique dans la transaction utilisée pour recevoir les messages depuis la file d'attente ainsi que pour spécifier l'arrivée à échéance automatique de cette transaction au terme de l'opération de service. La classe Orders encapsule la fonctionnalité de traitement des bons de commande. Dans cet exemple, elle ajoute les bons de commande à un dictionnaire. Les opérations peuvent accéder à la transaction à laquelle l'opération de service s'est inscrite depuis la classe Orders.

L'opération de service, outre traiter des bons de commande envoyés, envoie une réponse au client l'informant de l'état des commandes.

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

La liaison du client à utiliser est spécifiée à l'aide d'un fichier de configuration.

Le nom de la file d'attente MSMQ est spécifié dans la section appSettings de ce fichier de configuration. Le point de terminaison du service est défini dans la section System.ServiceModel de ce même fichier.

ms752246.note(fr-fr,VS.90).gifRemarque :
Le nom de la file d'attente MSMQ et l'adresse du point de terminaison utilisent des conventions d'adressage légèrement différentes. Le nom de la file d'attente MSMQ utilise un point (.) pour l'ordinateur local et des barre obliques inverses comme séparateur dans son chemin d'accès. L'adresse du point de terminaison WCF spécifie un schéma net.msmq:, utilise « localhost » pour l'ordinateur local et des barres obliques dans son chemin d'accès. Pour lire une file d'attente hébergée sur un ordinateur distant, remplacez « . » et « localhost » par le nom de cet ordinateur.

Un fichier .svc comportant le nom de la classe est utilisé pour héberger le code de service dans WAS.

Le fichier Service.svc contient une directive permettant de créer OrderProcessorService.

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

Ce fichier contient également une directive d'assembly permettant de vérifier que System.Transactions.dll est chargé.

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

Le client crée une étendue de transaction. La communication avec le service s'effectuant dans les limites de l'étendue de la transaction, elle est considérée comme une unité atomique dans laquelle l'intégralité des messages réussissent ou échouent. La transaction est validée par l'appel de la méthode Complete sur l'étendue de la transaction.

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

Le code du client implémente le contrat IOrderStatus pour pouvoir recevoir l'état des bons de commande envoyé par le service. Dans ce cas, le code affiche l'état des bons de commande.

[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 file d'attente de l'état des bons de commande est créée dans la méthode Main. La configuration du client intègre la configuration du service de l'état des bons de commande pour héberger le service de l'état des bons de commande, comme illustré dans l'exemple de configuration suivant.

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

Lorsque vous exécutez l'exemple, les activités du client et du service s'affichent sur leur console respective. Sur ces consoles, vous pouvez voir le serveur recevoir des messages du client. Appuyez sur le bouton ENTER de chaque console pour fermer le serveur et le client.

Le client affiche les informations d'état des bons de commande envoyées par le serveur :

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

Pour configurer, générer et exécuter l'exemple

  1. Assurez-vous d'avoir effectué la procédure figurant à la section Procédure d'installation unique pour les exemples Windows Communication Foundation. En outre, vous devez installer les composants d'activation WCF non HTTP :

    1. Dans le menu Démarrer, cliquez sur Panneau de configuration.
    2. Sélectionnez Programmes puis Programme et fonctionnalités ou, en affichage classique, sélectionnez Programmes et fonctionnalités.
    3. Cliquez sur Activer ou désactiver des fonctionnalités Windows.
    4. Sous Résumé de fonctionnalités, cliquez sur Ajouter des fonctionnalités.
    5. Développez le nœud Microsoft .NET Framework 3.0, puis sélectionnez la fonctionnalité d'activation non-HTTP de Windows Communication Foundation.
  2. Pour générer l'édition C# ou Visual Basic .NET de la solution, conformez-vous aux instructions figurant dans la rubrique Génération des exemples Windows Communication Foundation.

  3. Exécutez le client en exécutant client.exe depuis une fenêtre de commande. Cette exécution génère la file d'attente et envoie un message à celle-ci. Laissez le client s'exécuter pour connaître le résultat de la lecture de ce message par le service.

  4. Le service d'activation MSMQ s'exécute comme service réseau par défaut. Par conséquent, la file d'attente utilisée pour activer l'application doit recevoir et lire les autorisations pour le service réseau. Cette spécification peut être ajoutée à l'aide de Message Queuing et de la console MMC :

    1. Dans le menu Démarrer, cliquez sur Exécuter..., tapez Compmgmt.msc, puis appuyez sur la touche ENTRÉE de votre clavier.
    2. Sous Services et applications, développez Message Queuing.
    3. Cliquez sur Files d'attente privées.
    4. Cliquez avec le bouton droit de la souris sur la file d'attente (servicemodelsamples/Service.svc), puis sélectionnez Propriétés.
    5. Sous l'onglet Sécurité, cliquez sur Ajouter, puis attribuez les autorisations de lecture et de réception au service réseau.
  5. Configurez le service d'activation des processus Windows de sorte à assurer la prise en charge de l'activation MSMQ.

    1. Exécutez Inetmgr.exe.
    2. Pour activer le site Web par défaut permettant la communication sur le protocole net.msmq, vous devez ajouter une nouvelle liaison de site. À cette fin, exécutez le fichier de commandes AddMsmqSiteBinding.cmd situé dans le répertoire d'exemples.
  6. Si vous ne l'avez pas fait précédemment, assurez-vous que le service d'activation MSMQ est activé. Dans le menu Démarrer, cliquez sur Exécuter, puis tapez Services.msc. Recherchez l'adaptateur d'écouteur Net.Msmq dans la liste de services. Cliquez avec le bouton droit, puis sélectionnez Propriétés. Affectez au Type de démarrage la valeur Automatique, cliquez sur Appliquer, puis sur Démarrer. Cette étape doit être effectuée à une seule reprise, avant la première utilisation du service d'adaptateur de l'écouteur Net.Msmq.

  7. Pour exécuter l'exemple dans une configuration à un ou plusieurs ordinateurs, conformez-vous aux instructions figurant dans la rubrique Exécution des exemples Windows Communication Foundation. En outre, modifiez le code du client qui envoie le bon de commande en fonction du nom de l'ordinateur figurant dans l'URI de la file d'attente lors de l'envoi de ce bon. Utilisez le code suivant :

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

Avec le transport de la liaison netMsmqBinding, la sécurité est par défaut activée. Les propriétés MsmqAuthenticationMode et MsmqProtectionLevel déterminent toutes les deux le mode de sécurité du transport. Par défaut, le mode d'authentification a la valeur Windows et le niveau de protection a la valeur Sign. Pour que MSMQ fournisse la fonctionnalité d'authentification et de signature, il doit faire partie d'un domaine. Si vous exécutez cet exemple sur un ordinateur ne faisant pas partie d'un domaine, vous obtenez l'erreur suivante : « Le certificat Message Queuing interne pour l'utilisateur n'existe pas ».

Pour exécuter l'exemple sur un ordinateur associé à un groupe de travail

  1. Si votre ordinateur ne fait pas partie d'un domaine, désactivez la sécurité du transport en affectant au mode d'authentification et au niveau de protection la valeur None, tel qu'indiqué dans l'exemple de configuration suivant.

    <bindings>
        <netMsmqBinding>
            <binding configurationName="TransactedBinding">
                <security mode="None"/>
            </binding>
        </netMsmqBinding>
    </bindings>
    
  2. Modifiez la configuration du serveur et du client avant d'exécuter l'exemple.

    ms752246.note(fr-fr,VS.90).gifRemarque :
    L'affectation de None à security mode revient à affecter None aux modes de sécurité MsmqAuthenticationMode, MsmqProtectionLevel et Message.

  3. Pour permettre l'activation sur un ordinateur associé à un groupe de travail, le service d'activation et le processus de travail doivent tous deux être exécutés sous un compte d'utilisateur spécifique (compte identique pour les deux) et les listes ACL correspondant à ce compte doivent figurer dans la file d'attente.

    Pour modifier l'identité sous laquelle s'exécute le processus de travail :

    1. Exécutez Inetmgr.exe.
    2. Sous Pools d'applications, cliquez avec le bouton droit de la souris sur AppPool (en général DefaultAppPool), puis choisissez Définir les valeurs par défaut des pools d'applications.
    3. Modifiez les propriétés Identity en fonction du compte d'utilisateur à utiliser.

    Pour modifier l'identité sous laquelle s'exécute le service d'activation :

    1. Exécutez Services.msc.
    2. Cliquez avec le bouton droit de la souris sur Net.MsmqListener Adapter, puis choisissez Propriétés.
  4. Modifiez le compte figurant dans l'onglet Ouverture de session.

  5. Au niveau des groupes de travail, le service doit également s'exécuter à l'aide d'un jeton non restreint. Pour ce faire, utilisez la ligne suivante dans une fenêtre de commande :

    sc sidtype netmsmqactivator unrestricted
    

Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.