Duplex Workflow Service, exemple
Cette exemple illustre comment établir une communication duplex asynchrone entre deux services. Cet exemple illustre également comment établir une communication localhost-à-workflow en utilisant des messages. Dans le cadre d'une communication duplex entre deux services, ces deux services doivent échanger un contexte avant que la communication ne puisse être établie, et ce dans les deux sens. Le service à l'origine de la communication reçoit le contexte dans la réponse à son message. 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.
Remarque : |
---|
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.
Les messages sont également utilisés pour assurer la communication entre le localhost et le service. Le localhost expose un point de terminaison connu que le service peut utiliser pour le rappel. Cet exemple implémente un type LocalWorkflowServiceHost
qui permet de créer l'écouteur local ainsi que l'hôte service du workflow pour le service hébergé.
Cet exemple contient les entités communicantes suivantes :
Hôte client
L'hôte client communique avec le workflow client en appelant des opérations surIReverseContract
. Lorsque l'hôte client appelle d'abord l'opérationBeginWork
, le workflow client est généré. En réponse à l'opérationBeginWork
, le workflow client renvoie un message contenant le contexte lui correspondant. Le canal créé par l'hôte pour communiquer avec le workflow client dispose à présent du contexte nécessaire à la poursuite de la communication. Cet exemple illustre la manière dont l'hôte client envoie plusieurs éléments de travail à un workflow client en utilisant le même canal.
Pour que le workflow puisse communiquer avec l'hôte client, le client dispose d'une point de terminaison connu à partir duquel il procède à l'écoute. Dans cet exemple, ce point de terminaison s'appelleHostEndPoint
. LeLocalWorkflowServiceHost
est utilisé pour créer respectivement ce point de terminaison pour l'hôte client et l'hôte de service du workflow pour le workflow client.LocalWorkflowServiceHost localHost = new LocalWorkflowServiceHost(typeof(ClientWorkflow),new ClientHost()); localHost.WorkflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e) { Console.WriteLine("WorkflowTerminated: " + e.Exception.Message); }; localHost.WorkflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) { Console.WriteLine("WorkflowCompleted: " + e.WorkflowInstance.InstanceId.ToString()); }; localHost.Open();
Workflow client (exposé sous la forme d'un service)
Le workflow client implémenteIReverseContract
. Le workflow de service utilise cette implémentation, tel qu'illustré dans l'exemple précédent, afin de communiquer avec le workflow client. Le workflow client appelle d'abord l'opérationBeginWorkflow
, qui crée le workflow de service. La réponse retourne le contexte du workflow de service, utilisé par la suite par le workflow client pour pouvoir communiquer avec le workflow de service. Dans le cadre de l'opérationBeginWorkflow
, le workflow client transfère sa propre référence de point de terminaison au workflow de service, laquelle contient l'adresse de ce point ainsi que les en-têtes de contexte. Le workflow de service utilise cette adresse afin de communiquer de manière asynchrone avec le workflow client.
Le gestionnaire d'événementsWaitForBeginWork
à l'état initial implémente une activité de code nomméeDoSetReturnAddress
. Cette activité définit la référence de point de terminaison envoyée au workflow de service, tel qu'illustré dans l'exemple suivant.private void SetReturnAddress(object sender, EventArgs e) { EndpointAddress epr = ContextManager.CreateEndpointAddress(ReturnUri, this.ReceiveWorkItemComplete); ReturnAddress = EndpointAddress10.FromEndpointAddress(epr); DebugOutput("[ClientWorkflow:SetReturnAddress] " + epr.Headers[0].GetValue<string>()); }
Hôte de service
Cet exemple implémente un hôte de service de workflow. Il ouvre un écouteur qui écoute les demandes provenant du client. La première demande effectuée par le client génère une instance du workflow de service. Toutes les demandes suivantes sont acheminées vers la même instance de workflow, ces demandes transportant le contexte dans l'en-tête de leur message.Workflow de service (exposé sous la forme d'un service)
Le workflow de service implémenteIForwardContract
. Le workflow de service dans l'opérationBeginWorkflow
reçoit la référence de point de terminaison correspondant au workflow client. Le workflow de service applique cette référence à l'activité Send, laquelle envoie un message de manière asynchrone au workflow client. Le gestionnaire d'événementsWaitForBeginWorkflow
fournit l'activitéBeginWorkflow
Receive. L'activité Receive contient une activité de code nomméeApplyReturnAddress
, laquelle utilise l'adresse de retour dans l'activité Send afin d'envoyer un message au workflow client, tel qu'illustré dans le code suivant.private void ApplyReturnAddress(object sender, EventArgs e) { // apply ReturnAddress to ReverseEndpoint EndpointAddress epr = ReturnAddress.ToEndpointAddress(); ContextManager.ApplyEndpointAddress( this.SendWorkItemComplete, epr); DebugOutput("[ServiceWorkflow:ApplyReturnAddress] " + epr.Headers[0].GetValue<string>()); }
La classe
LocalWorkflowServiceHost
crée l'infrastructure nécessaire à la communication d'hôte à workflow. Le service de workflow local effectue principalement deux tâches :- Il crée l'écouteur local permettant à l'hôte d'écouter les messages provenant du workflow.
- Il instancie l'hôte WorkflowServiceHost afin de créer l'écouteur nécessaire au workflow.
Cette classe fournit également des fonctions d'assistance permettant à l'hôte de conserver le contexte utilisé pour communiquer avec le workflow. Si l'hôte se recycle, ce contexte est utilisé pour communiquer avec l'instance de workflow.
Le projet WorkflowServiceUtility fournit toutes les fonctions d'assistance nécessaires à la manipulation du contexte. Il fournit les fonctions permettant d'extraire le contexte du canal, de l'appliquer à ce dernier et d'appliquer l'adresse du point de terminaison à l'activité Send.
Pour configurer, générer et exécuter l'exemple
Pour installer les fournisseurs de persistance, exécutez le script CreateStores.cmd indiqué dans la rubrique One-Time Setup Procedure for the Windows Communication Foundation Samples.
Téléchargez Utilitaires de service de workflow, puis enregistrez-le de sorte à ce que les dossiers DuplexWorkflowService et WorkflowServiceUtility figurent dans le même dossier parent.
Si vous ne souhaitez pas utiliser de fournisseurs de persistance, spécifiez-le dans la section
<WorkflowRuntime>
des fichiers App.config.Cet exemple utilise deux bases de données de persistance. Le workflow de service utilise
NetFx35Samples_ServiceWorkflowStore
, tandis que le client utiliseNetFx35Samples_ClientWorkflowStore
. Vous pouvez créer ces magasins dans SQL Server ou SQL Server Express. Les chaînes de connexion actuelles situées dans les fichiers App.config partent du principe que vous utilisez SQL Server Express. Si vous créez les magasins dans SQL Server, assurez-vous de modifier les chaînes de connexion des fichiers App.config en conséquence.Lors de l'exécution de l'hôte client et de l'hôte de service, appuyez sur Y dans la fenêtre de console pour traiter les éléments de travail. Vous pouvez envoyer plusieurs éléments de travail pour traitement. Si vous arrêtez, puis redémarrez le client, il reprend là où il a été arrêté.
Pour tester la longévité des services, arrêtez à la fois l'application du service et celle du client, puis redémarrez l'application cliente suivie de celle du service. Cet ordre de redémarrage doit être respecté, le workflow de service tentant de renvoyer des messages au client dès lors qu'il s'exécute, or si le client n'est pas disponible, vous recevrez une exception.
Sur le client, le contexte est stocké dans le fichier Client.ctx. Ce fichier est stocké dans le répertoire de \bin de votre exemple. Lorsque vous rouvrez le client, il vérifie si le fichier est présent. Si le fichier est présent, il applique le contexte stocké au canal créé. Si le service de workflow est arrivé à son terme et si vous ouvrez le client à l'aide du fichier Client.ctx figurant encore dans votre répertoire \bin, il essaie d'appliquer le contexte y figurant au canal. Vous recevrez alors une erreur, l'instance de workflow avec laquelle vous souhaitez communiquer étant absente. Supprimez le fichier et réessayez.