Windows Communication Foundation naar Message Queuing
Het WcfToMsmq-voorbeeld laat zien hoe een WCF-toepassing (Windows Communication Foundation) een bericht kan verzenden naar een MSMQ-toepassing (Message Queuing). De service is een zelf-hostende consoletoepassing waarmee u de service die berichten in de wachtrij ontvangt, kunt observeren. De service en client hoeven niet tegelijkertijd te worden uitgevoerd.
De service ontvangt berichten uit de wachtrij en verwerkt orders. De service maakt een transactionele wachtrij en stelt een bericht ontvangen berichthandler in, zoals wordt weergegeven in de volgende voorbeeldcode.
static void Main(string[] args)
{
if (!MessageQueue.Exists(
ConfigurationManager.AppSettings["queueName"]))
MessageQueue.Create(
ConfigurationManager.AppSettings["queueName"], true);
//Connect to the queue
MessageQueue Queue = new
MessageQueue(ConfigurationManager.AppSettings["queueName"]);
Queue.ReceiveCompleted +=
new ReceiveCompletedEventHandler(ProcessOrder);
Queue.BeginReceive();
Console.WriteLine("Order Service is running");
Console.ReadLine();
}
Wanneer een bericht in de wachtrij wordt ontvangen, wordt de berichtenhandler ProcessOrder
aangeroepen.
public static void ProcessOrder(Object source,
ReceiveCompletedEventArgs asyncResult)
{
try
{
// Connect to the queue.
MessageQueue Queue = (MessageQueue)source;
// End the asynchronous receive operation.
System.Messaging.Message msg =
Queue.EndReceive(asyncResult.AsyncResult);
msg.Formatter = new System.Messaging.XmlMessageFormatter(
new Type[] { typeof(PurchaseOrder) });
PurchaseOrder po = (PurchaseOrder) msg.Body;
Random statusIndexer = new Random();
po.Status = PurchaseOrder.OrderStates[statusIndexer.Next(3)];
Console.WriteLine("Processing {0} ", po);
Queue.BeginReceive();
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
De service extraheert de hoofdtekst van het ProcessOrder
MSMQ-bericht en verwerkt de volgorde.
De naam van de MSMQ-wachtrij wordt opgegeven in een app Instellingen sectie van het configuratiebestand, zoals wordt weergegeven in de volgende voorbeeldconfiguratie.
<appSettings>
<add key="orderQueueName" value=".\private$\Orders" />
</appSettings>
Notitie
De wachtrijnaam maakt gebruik van een punt (.) voor de lokale computer en backslash-scheidingstekens in het pad.
De client maakt een inkooporder en verzendt de inkooporder binnen het bereik van een transactie, zoals wordt weergegeven in de volgende voorbeeldcode.
// Create the purchase order
PurchaseOrder po = new PurchaseOrder();
// Fill in the details
...
OrderProcessorClient client = new OrderProcessorClient("OrderResponseEndpoint");
MsmqMessage<PurchaseOrder> ordermsg = new MsmqMessage<PurchaseOrder>(po);
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
client.SubmitPurchaseOrder(ordermsg);
scope.Complete();
}
Console.WriteLine("Order has been submitted:{0}", po);
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
De client gebruikt een aangepaste client om het MSMQ-bericht naar de wachtrij te verzenden. Omdat de toepassing die het bericht ontvangt en verwerkt, een MSMQ-toepassing is en geen WCF-toepassing, is er geen impliciet servicecontract tussen de twee toepassingen. We kunnen dus geen proxy maken met behulp van het hulpprogramma Svcutil.exe in dit scenario.
De aangepaste client is in wezen hetzelfde voor alle WCF-toepassingen die gebruikmaken van de binding voor het MsmqIntegration
verzenden van berichten. In tegenstelling tot andere clients bevat het geen reeks servicebewerkingen. Het is alleen een verzendberichtbewerking.
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true, Action = "*")]
void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
}
public partial class OrderProcessorClient : System.ServiceModel.ClientBase<IOrderProcessor>, IOrderProcessor
{
public OrderProcessorClient(){}
public OrderProcessorClient(string configurationName)
: base(configurationName)
{ }
public OrderProcessorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress address)
: base(binding, address)
{ }
public void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg)
{
base.Channel.SubmitPurchaseOrder(msg);
}
}
Wanneer u het voorbeeld uitvoert, worden de client- en serviceactiviteiten weergegeven in zowel de service- als clientconsolevensters. U ziet dat de service berichten van de client ontvangt. Druk in elk consolevenster op Enter om de service en client af te sluiten. Houd er rekening mee dat omdat wachtrijen in gebruik zijn, de client en service niet tegelijkertijd actief hoeven te zijn. U kunt bijvoorbeeld de client uitvoeren, de client afsluiten en vervolgens de service starten en de berichten nog steeds ontvangen.
Notitie
Voor dit voorbeeld is de installatie van Message Queuing vereist. Zie de installatie-instructies in Message Queuing.
Het voorbeeld instellen, bouwen en uitvoeren
Zorg ervoor dat u de eenmalige installatieprocedure voor de Windows Communication Foundation-voorbeelden hebt uitgevoerd.
Als de service eerst wordt uitgevoerd, wordt gecontroleerd of de wachtrij aanwezig is. Als de wachtrij niet aanwezig is, maakt de service er een. U kunt de service eerst uitvoeren om de wachtrij te maken of u kunt er een maken via MSMQ Queue Manager. Volg deze stappen om een wachtrij te maken in Windows 2008.
Open Serverbeheer in Visual Studio 2012.
Vouw het tabblad Functies uit.
Klik met de rechtermuisknop op privéberichtenwachtrijen en selecteer vervolgens Nieuwe>privéwachtrij.
Schakel het selectievakje Transactioneel in.
Voer de
ServiceModelSamplesTransacted
naam in van de nieuwe wachtrij.
Als u de C# of Visual Basic-editie van de oplossing wilt bouwen, volgt u de instructies in het bouwen van de Windows Communication Foundation-voorbeelden.
Als u het voorbeeld wilt uitvoeren in een configuratie met één computer, volgt u de instructies in Het uitvoeren van de Windows Communication Foundation-voorbeelden.
Het voorbeeld uitvoeren op computers
Kopieer de serviceprogrammabestanden uit de map \service\bin\ onder de taalspecifieke map naar de servicecomputer.
Kopieer de clientprogrammabestanden uit de map \client\bin\ onder de taalspecifieke map naar de clientcomputer.
Wijzig in het bestand Client.exe.config het adres van het clienteindpunt om de naam van de servicecomputer op te geven in plaats van '.'.
Start Service.exe vanaf een opdrachtprompt op de servicecomputer.
Start Client.exe vanaf een opdrachtprompt op de clientcomputer.