Partager via


Activation MSMQ

L’exemple MsmqActivation montre comment héberger des applications dans le service d’activation de processus Windows (WAS) lues à partir d’une file d’attente de messages. Cet exemple utilise le netMsmqBinding et est basé sur l’exemple Two-Way Communication. Le service dans ce cas est une application hébergée sur le web, tandis que le client est auto-hébergé et envoie les résultats vers la console pour observer l’état des bons de commande soumis.

Remarque

La procédure d’installation et les instructions de génération de cet exemple se trouvent à la fin de cette rubrique.

Windows Process Activation Service (WAS), le nouveau mécanisme d’activation de processus pour Windows Server 2008, fournit des fonctionnalités de type IIS qui étaient auparavant uniquement disponibles pour les applications http aux applications qui utilisent des protocoles non HTTP. Windows Communication Foundation (WCF) utilise l’interface de l’adaptateur d’écouteur pour communiquer les demandes d’activation reçues sur les protocoles non HTTP pris en charge par WCF, tels que TCP, canaux nommés et MSMQ. La fonctionnalité de réception de requêtes sur des protocoles non HTTP est hébergée par les services Windows gérés s’exécutant dans SMSvcHost.exe.

Le service d’adaptateur d’écouteur Net.Msmq (NetMsmqActivator) active les applications mises en file d’attente en fonction des messages de la file d’attente.

Le client envoie des commandes d’achat au service dans le cadre d'une transaction. Le service reçoit les commandes dans le cadre d'une transaction et les traite. Le service rappelle ensuite le client avec l’état de la 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 IOrderProcessor de service définit les opérations de service unidirectionnelles qui fonctionnent avec la mise en file 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 est l’URI de la file d’attente utilisée pour renvoyer l’état de la commande au client. L’application de traitement des commandes 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 à lequel envoyer l’état de la 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 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é. OperationBehaviorAttribute est appliqué à l'opération de service pour spécifier l'enrôlement automatique dans la transaction utilisée pour recevoir le message de la file d'attente et l'achèvement automatique de la transaction une fois l'opération de service terminée. La Orders classe encapsule la fonctionnalité de traitement des commandes. Dans ce cas, il ajoute le bon de commande à un dictionnaire. La transaction à laquelle l'opération de service est associée est disponible pour les opérations de la classe Orders.

L’opération de service, en plus de traiter le bon de commande soumis, répond au client sur l’état de la commande.

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 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 une section appSettings du fichier de configuration. Le point de terminaison du service est défini dans la section System.serviceModel du fichier de configuration.

Remarque

Le nom et l’adresse de point de terminaison de la file d’attente MSMQ 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 barres 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 à partir d’une file d’attente hébergée sur l’ordinateur distant, remplacez « » et « localhost » par le nom de l’ordinateur distant.

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

Le fichier Service.svc lui-même contient une directive pour créer le OrderProcessorServicefichier .

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

Le fichier Service.svc contient également une directive d’assembly pour vous assurer que System.Transactions.dll est chargé.

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

Le client crée un périmètre de transaction. La communication avec le service se produit dans l’étendue de la transaction, ce qui lui permet d’être traitée comme une unité atomique où tous les 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/ServiceModelSamplesOrder/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 depuis le service. Dans ce cas, il imprime l’état de la 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 inclut la configuration du service d’état de commande pour héberger le service d’état de commande, comme indiqué 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 sont affichées dans les fenêtres serveur et console cliente. Vous pouvez voir que le serveur reçoit des messages du client. Appuyez sur Entrée dans chaque fenêtre de console pour arrêter le serveur et le client.

Le client affiche les informations d’état 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. Vérifiez que IIS 7.0 est installé, car il est nécessaire pour l’activation WAS.

  2. Assurez-vous d’avoir effectué la 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 , choisissez Panneau de configuration.

    2. Sélectionnez Programmes et fonctionnalités.

    3. Cliquez sur Activer ou désactiver les fonctionnalités Windows.

    4. Sous Résumé des fonctionnalités, cliquez sur Ajouter des fonctionnalités.

    5. Développez le nœud Microsoft .NET Framework 3.0 et vérifiez la fonctionnalité d’activation non HTTP de Windows Communication Foundation .

  3. Pour générer l’édition C# ou Visual Basic .NET de la solution, conformez-vous aux instructions figurant dans Building the Windows Communication Foundation Samples.

  4. Exécutez le client en exécutant client.exe à partir d’une fenêtre de commande. Cela crée la file d’attente et envoie un message à celui-ci. Laissez le client en cours d’exécution pour voir le résultat du service lisant le message

  5. Le service d’activation MSMQ s’exécute en tant que service réseau par défaut. Par conséquent, la file d’attente utilisée pour activer l’application doit avoir des autorisations de réception et d’aperçu 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, puis tapez et appuyez Compmgmt.msc sur Entrée.

    2. Sous Services et applications, développez Message Queuing.

    3. Cliquez sur Files d’attente privées.

    4. Cliquez avec le bouton droit sur la file d’attente (servicemodelsamples/Service.svc) et choisissez Propriétés.

    5. Sous l’onglet Sécurité , cliquez sur Ajouter et donnez un aperçu et recevez des autorisations sur le service réseau.

  6. Configurez le service d’activation de processus Windows (WAS) pour prendre en charge l’activation MSMQ.

    En guise de commodité, les étapes suivantes sont implémentées dans un fichier batch appelé AddMsmqSiteBinding.cmd situé dans l’exemple de répertoire.

    1. Pour prendre en charge l’activation net.msmq, le site web par défaut doit d’abord être lié au protocole net.msmq. Pour ce faire, utilisez appcmd.exe, qui est installé avec l’ensemble d’outils de gestion IIS 7.0. À partir d'une invite de commandes avec élévation de privilèges (administrateur), exécutez la commande suivante.

      %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site"
      -+bindings.[protocol='net.msmq',bindingInformation='localhost']
      

      Remarque

      Cette commande est une seule ligne de texte.

      Cette commande ajoute une liaison de site net.msmq au site web par défaut.

    2. Bien que toutes les applications d’un site partagent une liaison net.msmq commune, chaque application peut activer la prise en charge individuellement de net.msmq. Pour activer net.msmq pour l’application /servicemodelsamples, exécutez la commande suivante à partir d’une invite de commandes avec élévation de privilèges.

      %windir%\system32\inetsrv\appcmd.exe set app "Default Web Site/servicemodelsamples" /enabledProtocols:http,net.msmq
      

      Remarque

      Cette commande est une seule ligne de texte.

      Cette commande permet à l’application /servicemodelsamples d’être accessible à l’aide http://localhost/servicemodelsamples et net.msmq://localhost/servicemodelsamples.

  7. Si vous ne l’avez pas fait précédemment, vérifiez que le service d’activation MSMQ est activé. Dans le menu Démarrer , cliquez sur Exécuter, puis tapez Services.msc. Recherchez la liste des services pour l’adaptateur d’écouteur Net.Msmq. Effectuez un clic droit et sélectionnez Propriétés. Définissez le type de démarragesur Automatique, cliquez sur Appliquer , puis cliquez sur le bouton Démarrer . Cette étape ne doit être effectuée qu’une seule fois avant la première utilisation du service d’adaptateur d’écouteur Net.Msmq.

  8. Pour exécuter l’exemple dans une configuration monoposte ou multiposte, suivez les instructions de Exécution des exemples Windows Communication Foundation. En outre, modifiez le code sur le client qui envoie le bon de commande pour refléter le nom de l’ordinateur dans l’URI de la file d’attente lors de l’envoi de la commande d’achat. Utilisez le code suivant :

    client.SubmitPurchaseOrder(po, "net.msmq://localhost/private/ServiceModelSamples/OrderStatus");
    
  9. Supprimez la liaison de site net.msmq que vous avez ajoutée dans le cadre de cet exemple.

    Pour plus de commodité, les étapes suivantes sont implémentées dans un fichier de commandes appelé RemoveMsmqSiteBinding.cmd situé dans l’exemple de répertoire :

    1. Supprimez net.msmq de la liste des protocoles activés en exécutant la commande suivante à partir d’une invite de commandes avec élévation de privilèges.

      %windir%\system32\inetsrv\appcmd.exe set app "Default Web Site/servicemodelsamples" /enabledProtocols:http
      

      Remarque

      Cette commande est une seule ligne de texte.

    2. Supprimez la liaison du site net.msmq en exécutant la commande suivante à partir d'une invite de commandes avec élévation de privilèges.

      %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" --bindings.[protocol='net.msmq',bindingInformation='localhost']
      

      Remarque

      Cette commande est une seule ligne de texte.

    Avertissement

    L’exécution du fichier batch réinitialise DefaultAppPool à exécuter à l’aide de .NET Framework version 2.0.

Avec le transport de liaison netMsmqBinding, la sécurité est activée par défaut. Deux propriétés, MsmqAuthenticationMode et MsmqProtectionLevel, ensemble déterminent le type de sécurité du transport. Par défaut, le mode d’authentification est défini Windows sur et le niveau de protection est défini sur Sign. Pour que MSMQ fournisse la fonctionnalité d’authentification et de signature, elle doit faire partie d’un domaine. Si vous exécutez cet exemple sur un ordinateur qui ne fait pas partie d’un domaine, l’erreur suivante est reçue : « Le certificat de mise en file d’attente de message interne de l’utilisateur n’existe pas ».

Pour exécuter l’exemple sur un ordinateur joint à un groupe de travail

  1. Si votre ordinateur ne fait pas partie d’un domaine, désactivez la sécurité du transport en définissant le mode d’authentification et le niveau de protection sur aucun, comme indiqué dans l’exemple de configuration suivant.

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

    Remarque

    Définir security mode sur None équivaut à définir la sécurité de MsmqAuthenticationMode, MsmqProtectionLevel et Message sur None.

  3. Pour activer l’activation dans un ordinateur joint à un groupe de travail, le service d’activation et le processus de travail doivent être exécutés avec un compte d’utilisateur spécifique (doit être identique pour les deux) et la file d’attente doit avoir des listes de contrôle d’accès pour le compte d’utilisateur spécifique.

    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 sur AppPool (généralement DefaultAppPool) et choisissez Définir les valeurs par défaut du pool d’applications....

    3. Modifiez les propriétés d’identité pour utiliser le compte d’utilisateur spécifique.

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

    1. Exécutez Services.msc.

    2. Cliquez avec le bouton droit sur l’adaptateur Net.MsmqListener, puis choisissez Propriétés.

  4. Modifiez le compte sous l’onglet LogOn .

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

    sc sidtype netmsmqactivator unrestricted
    

Voir aussi