Partager via


Conversations, exemple

Cet exemple illustre la manière dont un service de workflow peut entretenir des conversations parallèles avec plusieurs clients sur le même contrat. L'exemple illustre comment mettre en relation des messages envoyés pour le même contrat et la même opération mais qui doivent être gérés différemment car ils sont envoyés par différents clients. Pour permettre les conversations parallèles, cet exemple utilise la fonctionnalité de contexte de conversation fournie par les services de workflow.

Bb410775.note(fr-fr,VS.90).gifRemarque :
Cet exemple requiert l'installation de .NET Framework version 3.5 pour être généré et exécuté. Visual Studio 2008 est nécessaire pour l'ouverture des fichiers projet et solution.

Pour plus d'informations sur la configuration de cet exemple, consultez One-time Setup Procedure for Windows Communication Foundation Samples.

Cet exemple utilise également une communication duplex asynchrone afin de permettre au service de workflow et au client de communiquer de manière asynchrone. Dans le cadre d'une communication duplex, les deux applications doivent échanger un contexte pour permettre à la communication de commencer. Le service à l'origine de la conversation reçoit le contexte en réponse à son message. Les services de workflow fournissent ce type de fonctionnalité. Pour assurer la prise en charge de la communication entre le service recevant le premier message et le service initiant la communication, ce dernier doit envoyer les informations relatives à son contexte dans ce premier message. L'illustration suivante présente l'architecture de l'exemple.

Conversations, exemple

Cet exemple implémente le scénario suivant.

Un client envoie une demande correspondant à une commande. Avant d'expédier cette commande, le fournisseur souhaite obtenir des devis de trois transporteurs. Le fournisseur envoie un message à ces trois transporteurs. Chacun de ces transporteurs lui renvoie un devis en appelant la même opération sur le même contrat. Dans la mesure où le workflow du fournisseur utilise le contexte de conversation, cette fonctionnalité peut mettre en relation ces devis avec l'activité Receive adéquate et ainsi permettre la poursuite de leur traitement. Le fournisseur reçoit tous les devis, choisit le moins cher et l'envoie au client.

Cinq entités communiquent dans cet exemple :

  • Service du client
    Le service du client envoie les détails relatifs à la commande au fournisseur, ainsi que le contexte que le service de ce dernier utilisera pour répondre au service du client. Ce workflow de base contient une activité Send initiale, qui envoie le message de demande de bon de commande, ainsi que le bon de commande et le contexte sous forme de charges utiles. Une activité Receive attend la réponse du service du fournisseur.
    Le contexte envoyé par le service du client est associé à l'activité Receive. Le gestionnaire « before send » de l'activité Send contient le code permettant d'obtenir le contexte auprès de l'activité Receive. L'activité Receive comporte la méthode GetContext suivante, laquelle est appelée pour obtenir le contexte.

    private void PrepareOrder(object sender, SendActivityEventArgs e)
    {
        this.order.Amount = 1000;
        this.order.OrderId = 1234;
        this.contextToSend = this.ReceiveOrderDetails.Context;
    }
    
  • Service du fournisseur
    Le service du fournisseur communique avec trois transporteurs. Pour ce faire, il utilise un jeton de contexte unique pour chaque conversation ainsi qu'une communication duplex asynchrone. Le contexte est envoyé dans le corps du message transmis via la communication établie entre les services du fournisseur et du client.
    Avant de communiquer avec les transporteurs, le service du fournisseur reçoit d'abord un message du service du client. Ce message contient le contexte que le service du fournisseur utilisera pour répondre au service du client. Le workflow du service du fournisseur applique ce contexte à l'activité Send utilisée pour envoyer le message au service du client. Le code qui implémente cette fonctionnalité figure dans le gestionnaire de code de l'activité de code, à l'intérieur de la première activité Receive, comme l'illustre le code suivant.

    private void AcceptOrder(object sender, EventArgs e)
    {
        Console.WriteLine("Order Received...");
        this.supplierAck = "Order Received on " + DateTime.Now;
        this.SendOrderDetails.Context = this.customerContext;
    }
    

    Lorsque le service du fournisseur reçoit le message du client, le fournisseur initie trois conversations parallèles, chacune avec l'un des trois transporteurs. Chaque branche de conversation dispose d'une activité Send et Receive, comme l'indique l'illustration précédente. Les activités Send de chaque branche envoient un message à chaque transporteur. Les activités Receive correspondantes de chaque branche doivent ensuite extraire la réponse de chacun des transporteurs. Pour ce faire, les activités Send doivent envoyer un contexte unique via la charge utile des messages. Les transporteurs utilisent ensuite ce contexte figurant dans l'en-tête de message pour envoyer leur réponse contenant leur devis.
    Par défaut, chaque activité Receive dispose d'un contexte racine. Pour conférer un caractère unique à ce contexte Receive, les activités Receive définissent un contexte dont l'étendue est limitée par leur activité parente, à l'exclusion de leur activité racine. Dans l'exemple suivant, la propriété du jeton de contexte de chaque activité Receive dans la conversation parallèle dispose d'un nom unique dont l'étendue est limitée par l'activité parallèle qui la contient. Le contexte obtenu par l'activité Send de chaque conversation parallèle auprès de l'activité Receive est propre à chaque activité Receive. Ce contexte unique est également utilisé pour attribuer un nom à la file d'attente à partir de laquelle les activités Receive écoutent. Lorsque les transporteurs envoient leurs messages de réponse (devis), la couche de distribution du service de workflow utilise le contexte contenu dans leur en-tête afin d'attribuer un nom à la file d'attente dans laquelle elle place ces messages et que l'activité Receive consulte ensuite pour les récupérer.
    private void PrepareShipper2Request(object sender, SendActivityEventArgs e)
    {
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine("RequestShippingQuote from Shipper2");
    Console.ResetColor();
    this.contextShipper2 = this.ReceiveQuoteFromShipper2.Context;
    }
    Les workflows des transporteurs reçoivent une demande de devis de la part du fournisseur ainsi que le contexte. Ce contexte est appliqué à l'activité Send qui envoie le message de réponse au fournisseur, comme l'illustre le code suivant.

    private void AcceptQuoteRequest(object sender, EventArgs e)
    {
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine("Received ShippingQuote Request");
        this.supplierAck = "Working on quote...";
        Console.ResetColor();
        this.SendShippingQuote.Context(this.supplierContext);
    }
    

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

  1. Par défaut, cet exemple n'utilise pas de persistance. Si vous souhaitez utiliser la persistance, vous devez ajouter l'entrée <WorkflowRuntime> au fichier App.config de chacune des solutions. Cette entrée doit figurer sous la section behaviors, comme l'illustre l'exemple suivant.

    <behaviors>
          <serviceBehaviors>
            <behavior name="ServiceBehavior"  >
              <serviceMetadata httpGetEnabled="false" />
              <serviceDebug includeExceptionDetailInFaults="true" />
              <workflowRuntime name="WorkflowServiceHostRuntime" validateOnCreate="true" enablePerformanceCounters="true">
                <services>
                  <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                       connectionString="Data Source=localhost\sqlexpress;Initial Catalog=ServiceModelSamples_ServiceWorkflowStore;Integrated Security=True;Pooling=False"
                       LoadIntervalSeconds="1" UnLoadOnIdle= "true" />
                </services>
              </workflowRuntime>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
  2. Outre l'entrée <WorkflowRuntime> sous la section behaviors, un service de persistance SQL est également ajouté. Exécutez le script CreateStores.cmd figurant dans la rubrique One-Time Setup Procedure for the Windows Communication Foundation Samples. Le script CreateStores.cmd crée la base de données ServiceModelSamples_ServiceWorkflowStore. Par défaut, cette base de données est créée dans une base de données SQL Server 2005 Express Edition. Assurez-vous que SQL Server Express est installé sur votre ordinateur. Si vous ne souhaitez pas installer SQL Server Express et préférez utiliser SQL Server à la place, veillez à modifier les chaînes de connexion des fichiers App.config permettant d'accéder aux bases de données de persistance.

  3. Lorsque tous les services de workflow sont en cours d'exécution, appuyez sur ENTRÉE dans le workflow client pour afficher la totalité des workflows communiquant les uns avec les autres. Le bon de commande est envoyé au fournisseur qui envoie ensuite des demandes de devis à tous les transporteurs. Une fois les devis reçus par le fournisseur, vous pouvez constater que le devis le moins élevé est renvoyé au client. Vous pouvez également vérifier les jetons de contexte utilisés dans chaque cas. Cette vérification permet de mieux comprendre le caractère unique des contextes envoyés à chaque transporteur.

Envoyer des commentaires sur cette rubrique à Microsoft.