Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
L’exemple de session montre comment envoyer et recevoir un ensemble de messages associés dans la communication mise en file d’attente sur le transport MsmQ (Message Queuing). Cet exemple utilise la netMsmqBinding liaison. Le service est une application console auto-hébergée pour vous permettre d’observer le service recevant des messages mis en file d’attente.
Remarque
La procédure d’installation et les instructions de génération de cet exemple se trouvent à la fin de cette rubrique.
Dans la communication en file d'attente, le client communique avec le service à l’aide d’une file d’attente. Plus précisément, le client envoie des messages à une file d’attente. Le service reçoit des messages de la file d’attente. Le service et le client n'ont donc pas besoin d'être en cours d’exécution simultanément pour communiquer via une file d’attente.
Parfois, un client envoie un ensemble de messages qui sont liés les uns aux autres dans un groupe. Lorsque les messages doivent être traités ensemble ou dans un ordre spécifié, une file d’attente peut être utilisée pour les regrouper, pour le traitement par une application de réception unique. Cela est particulièrement important lorsqu’il existe plusieurs applications de réception sur un groupe de serveurs et qu’il est nécessaire de s’assurer qu’un groupe de messages est traité par la même application de réception. Les sessions en file d’attente sont un mécanisme utilisé pour envoyer et recevoir un ensemble de messages connexes qui doivent être traités en même temps. Les sessions mises en file d’attente nécessitent une transaction pour présenter ce modèle.
Dans l’exemple, le client envoie un certain nombre de messages au service dans le cadre d’une session dans l’étendue d’une transaction unique.
Le contrat de service est IOrderTaker, qui définit un service unidirectionnel qui convient pour une utilisation avec des files d’attente. Le SessionMode contrat utilisé dans l’exemple de code suivant indique que les messages font partie de la session.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required)]
public interface IOrderTaker
{
[OperationContract(IsOneWay = true)]
void OpenPurchaseOrder(string customerId);
[OperationContract(IsOneWay = true)]
void AddProductLineItem(string productId, int quantity);
[OperationContract(IsOneWay = true)]
void EndPurchaseOrder();
}
Le service définit les opérations de service de telle sorte que la première opération s’inscrit dans une transaction, mais ne termine pas automatiquement la transaction. Les opérations suivantes s’inscrivent également dans la même transaction, mais ne se terminent pas automatiquement. La dernière opération de la session termine automatiquement la transaction. Ainsi, la même transaction est utilisée pour plusieurs appels d’opération dans le contrat de service. Si l’une des opérations lève une exception, la transaction est rétablie et la session est remise dans la file d’attente. Une fois la dernière opération terminée, la transaction est validée. Le service utilise PerSession pour InstanceContextMode recevoir tous les messages d’une session sur la même instance du service.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class OrderTakerService : IOrderTaker
{
PurchaseOrder po;
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = false)]
public void OpenPurchaseOrder(string customerId)
{
Console.WriteLine("Creating purchase order");
po = new PurchaseOrder(customerId);
}
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = false)]
public void AddProductLineItem(string productId, int quantity)
{
po.AddProductLineItem(productId, quantity);
Console.WriteLine("Product " + productId + " quantity " +
quantity + " added to purchase order");
}
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public void EndPurchaseOrder()
{
Console.WriteLine("Purchase Order Completed");
Console.WriteLine();
Console.WriteLine(po.ToString());
}
}
Le service est auto-hébergé. Lorsque vous utilisez le transport MSMQ, la file d’attente utilisée doit être créée à l’avance. Cette opération peut être effectuée manuellement ou via du code. Dans cet exemple, le service contient System.Messaging du code pour vérifier l’existence de la file d’attente et le crée, si nécessaire. Le nom de la file d’attente est lu à partir du fichier de configuration à l’aide de la AppSettings classe.
// Host the service within this EXE console application.
public static void Main()
{
// Get MSMQ queue name from app settings in configuration.
string queueName = ConfigurationManager.AppSettings["queueName"];
// Create the transacted MSMQ queue if necessary.
if (!MessageQueue.Exists(queueName))
MessageQueue.Create(queueName, true);
// Create a ServiceHost for the OrderTakerService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderTakerService)))
{
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHost to shutdown the service.
serviceHost.Close();
}
}
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 et spécifie la netMsmqBinding liaison.
<appSettings>
<!-- Use appSetting to configure MSMQ queue name. -->
<add key="queueName" value=".\private$\ServiceModelSamplesSession" />
</appSettings>
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.OrderTakerService"
behaviorConfiguration="CalculatorServiceBehavior">
...
<!-- Define NetMsmqEndpoint -->
<endpoint address="net.msmq://localhost/private/ServiceModelSamplesSession"
binding="netMsmqBinding"
contract="Microsoft.ServiceModel.Samples.IOrderTaker" />
...
</service>
</services>
...
</system.serviceModel>
Le client crée un périmètre de transaction. Tous les messages de la session sont envoyés à la file d’attente dans l’étendue de la transaction, ce qui lui permet d’être traité comme une unité atomique où tous les messages réussissent ou échouent. La transaction est validée en appelant Complete.
//Create a transaction scope.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
// Create a client with given client endpoint configuration.
OrderTakerClient client = new OrderTakerClient("OrderTakerEndpoint");
// Open a purchase order.
client.OpenPurchaseOrder("somecustomer.com");
Console.WriteLine("Purchase Order created");
// Add product line items.
Console.WriteLine("Adding 10 quantities of blue widget");
client.AddProductLineItem("Blue Widget", 10);
Console.WriteLine("Adding 23 quantities of red widget");
client.AddProductLineItem("Red Widget", 23);
// Close the purchase order.
Console.WriteLine("Closing the purchase order");
client.EndPurchaseOrder();
//Closing the client gracefully closes the connection and cleans up resources.
client.Close();
// Complete the transaction.
scope.Complete();
}
Remarque
Vous ne pouvez utiliser qu’une seule transaction pour tous les messages de la session et tous les messages de la session doivent être envoyés avant de valider la transaction. La fermeture du client ferme la session. Par conséquent, le client doit être fermé avant la fin de la transaction pour envoyer tous les messages de la session à la file d’attente.
Lorsque vous exécutez l’exemple, les activités du client et du service s’affichent dans les fenêtres de la console du service et du client. Vous pouvez voir le service recevoir des messages du client. Appuyez sur Entrée dans chaque fenêtre de console pour arrêter le service et le client. Étant donné que la mise en file d’attente est en cours d’utilisation, le client et le service n’ont pas besoin d’être opérationnel en même temps. Vous pouvez exécuter le client, l'arrêter, puis démarrer le service, et il continuera à recevoir ses messages.
Sur le client.
Purchase Order created
Adding 10 quantities of blue widget
Adding 23 quantities of red widget
Closing the purchase order
Press <ENTER> to terminate client.
Sur le service.
The service is ready.
Press <ENTER> to terminate service.
Creating purchase order
Product Blue Widget quantity 10 added to purchase order
Product Red Widget quantity 23 added to purchase order
Purchase Order Completed
Purchase Order: 7c86fef0-2306-4c51-80e6-bcabcc1a6e5e
Customer: somecustomer.com
OrderDetails
Order LineItem: 10 of Blue Widget @unit price: $2985
Order LineItem: 23 of Red Widget @unit price: $156
Total cost of this order: $33438
Order status: Pending
Configurer, générer et exécuter l’exemple
Assurez-vous d’avoir effectué la Procédure d’installation unique pour les exemples Windows Communication Foundation.
Pour générer l’édition C#, C++ ou Visual Basic .NET de la solution, suivez les instructions de création des exemples Windows Communication Foundation.
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.
Par défaut, la sécurité de transport est activée avec le NetMsmqBinding. Il existe deux propriétés pertinentes pour la sécurité du transport MSMQ, à savoir, MsmqAuthenticationMode et.MsmqProtectionLevelpar 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 et l’option d’intégration Active Directory pour MSMQ doit être installée. Si vous exécutez cet exemple sur un ordinateur qui ne répond pas à ces critères, vous recevez une erreur.
Exécuter l’exemple sur un ordinateur joint à un groupe de travail
Si votre ordinateur ne fait pas partie d’un domaine ou n’a pas d’intégration Active Directory installée, désactivez la sécurité du transport en définissant le mode d’authentification et le niveau
Nonede protection comme indiqué dans l’exemple de configuration suivant.<system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samples.OrderTakerService" behaviorConfiguration="OrderTakerServiceBehavior"> <host> <baseAddresses> <add baseAddress= "http://localhost:8000/ServiceModelSamples/service"/> </baseAddresses> </host> <!-- Define NetMsmqEndpoint --> <endpoint address= "net.msmq://localhost/private/ServiceModelSamplesSession" binding="netMsmqBinding" bindingConfiguration="Binding1" contract="Microsoft.ServiceModel.Samples.IOrderTaker" /> <!-- The mex endpoint is exposed at--> <!--http://localhost:8000/ServiceModelSamples/service/mex. --> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <bindings> <netMsmqBinding> <binding name="Binding1"> <security mode="None" /> </binding> </netMsmqBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="OrderTakerServiceBehavior"> <serviceMetadata httpGetEnabled="True"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>Veillez à modifier la configuration sur le serveur et le client avant d’exécuter l’exemple.
Remarque
Définir le mode
Nonede sécurité sur est équivalent à la MsmqAuthenticationModedéfinition, MsmqProtectionLeveletMessageà la sécurité surNone.