Tvåvägskommunikation
Tvåvägsexemplet visar hur du utför transacted two-way queued communication over MSMQ. Det här exemplet använder bindningen netMsmqBinding
. I det här fallet är tjänsten ett lokalt konsolprogram som gör att du kan observera att tjänsten tar emot köade meddelanden.
Kommentar
Installationsproceduren och bygginstruktionerna för det här exemplet finns i slutet av det här avsnittet.
Det här exemplet baseras på transacted MSMQ-bindningen.
I kökommunikation kommunicerar klienten till tjänsten med hjälp av en kö. Klienten skickar meddelanden till en kö och tjänsten tar emot meddelanden från kön. Tjänsten och klienten behöver därför inte köras samtidigt för att kommunicera med en kö.
Det här exemplet visar tvåvägskommunikation med hjälp av köer. Klienten skickar inköpsorder till kön inom omfånget för en transaktion. Tjänsten tar emot beställningarna, bearbetar ordern och anropar sedan klienten med statusen för ordern från kön inom omfånget för en transaktion. För att underlätta dubbelriktad kommunikation använder både klienten och tjänsten köer för att ange inköpsorder och orderstatus.
Tjänstkontraktet IOrderProcessor
definierar envägstjänståtgärder som passar användningen av köer. Tjänståtgärden innehåller svarsslutpunkten som ska användas för att skicka orderstatusarna till. Svarsslutpunkten är URI:n för kön för att skicka orderstatusen tillbaka till klienten. Beställningsbearbetningsprogrammet implementerar det här kontraktet.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po, string
reportOrderStatusTo);
}
Svarskontraktet för att skicka orderstatus anges av klienten. Klienten implementerar orderstatuskontraktet. Tjänsten använder den genererade proxyn för det här kontraktet för att skicka orderstatusen tillbaka till klienten.
[ServiceContract]
public interface IOrderStatus
{
[OperationContract(IsOneWay = true)]
void OrderStatus(string poNumber, string status);
}
Tjänståtgärden bearbetar den skickade inköpsordern. OperationBehaviorAttribute Tillämpas på tjänståtgärden för att ange automatisk registrering i en transaktion som används för att ta emot meddelandet från kön och automatiskt slutföra transaktioner när tjänståtgärden har slutförts. Klassen Orders
kapslar in funktioner för orderbearbetning. I det här fallet lägger den till inköpsordern i en ordlista. Den transaktion som tjänståtgärden registrerade i är tillgänglig för åtgärderna i Orders
klassen.
Tjänståtgärden svarar, förutom att bearbeta den skickade inköpsordern, tillbaka till klienten om beställningens status.
[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("ClientCallbackBinding");
OrderStatusClient client = new OrderStatusClient(msmqCallbackBinding, new EndpointAddress(reportOrderStatusTo));
// Please note that the same transaction that is used to dequeue the purchase order is used
// to send back order status.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
client.OrderStatus(po.PONumber, po.Status);
scope.Complete();
}
//Close the client.
client.Close();
}
MSMQ-könamnet anges i en app Inställningar avsnitt i konfigurationsfilen. Slutpunkten för tjänsten definieras i avsnittet System.ServiceModel i konfigurationsfilen.
Kommentar
MSMQ-könamnet och slutpunktsadressen använder lite olika adresseringskonventioner. MSMQ-könamnet använder en punkt (.) för den lokala datorn och omvänt snedstrecksavgränsare i sökvägen. WCF-slutpunktsadressen (Windows Communication Foundation) anger ett net.msmq:-schema, använder "localhost" för den lokala datorn och använder snedstreck i sökvägen. Om du vill läsa från en kö som finns på fjärrdatorn ersätter du "." och "localhost" till namnet på fjärrdatorn.
Tjänsten är lokalt installerad. När du använder MSMQ-transporten måste den kö som används skapas i förväg. Detta kan göras manuellt eller via kod. I det här exemplet kontrollerar tjänsten om kön finns och skapar den om det behövs. Könamnet läse från konfigurationsfilen. Basadressen används av ServiceModel Metadata Utility Tool (Svcutil.exe) för att generera proxyn till tjänsten.
// Host the service within this EXE console application.
public static void Main()
{
// Get MSMQ queue name from appSettings 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 OrderProcessorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
{
// 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();
}
}
Klienten skapar en transaktion. Kommunikationen med kön sker inom transaktionens omfång, vilket gör att den behandlas som en atomisk enhet där alla meddelanden lyckas eller misslyckas.
// Create a ServiceHost for the OrderStatus service type.
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderStatusService)))
{
// Open the ServiceHostBase to create listeners and start listening for order status messages.
serviceHost.Open();
// Create the purchase order.
...
// Create a client with given client endpoint configuration.
OrderProcessorClient client = new OrderProcessorClient("OrderProcessorEndpoint");
//Create a transaction scope.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
string hostName = Dns.GetHostName();
// Make a queued call to submit the purchase order.
client.SubmitPurchaseOrder(po, "net.msmq://" + hostName + "/private/ServiceModelSamplesTwo-way/OrderStatus");
// Complete the transaction.
scope.Complete();
}
//Close down the client.
client.Close();
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();
// Close the ServiceHost to shutdown the service.
serviceHost.Close();
}
Klientkoden implementerar IOrderStatus
kontraktet för att ta emot orderstatus från tjänsten. I det här fallet skrivs orderstatusen ut.
[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);
}
}
Orderstatuskön skapas i Main
-metoden. Klientkonfigurationen innehåller konfigurationen för orderstatustjänsten som värd för orderstatustjänsten, enligt följande exempelkonfiguration.
<appSettings>
<!-- Use appSetting to configure MSMQ queue name. -->
<add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderStatus" />
</appSettings>
<system.serviceModel>
<services>
<service
name="Microsoft.ServiceModel.Samples.OrderStatusService">
<!-- Define NetMsmqEndpoint -->
<endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderStatus"
binding="netMsmqBinding"
contract="Microsoft.ServiceModel.Samples.IOrderStatus" />
</service>
</services>
<client>
<!-- Define NetMsmqEndpoint -->
<endpoint name="OrderProcessorEndpoint"
address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor"
binding="netMsmqBinding"
contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
</client>
</system.serviceModel>
När du kör exemplet visas klient- och tjänstaktiviteterna i både tjänst- och klientkonsolfönstren. Du kan se att tjänsten tar emot meddelanden från klienten. Tryck på RETUR i varje konsolfönster för att stänga av tjänsten och klienten.
Tjänsten visar inköpsorderinformationen och anger att den skickar tillbaka orderstatusen till orderstatuskön.
The service is ready.
Press <ENTER> to terminate service.
Processing Purchase Order: 124a1f69-3699-4b16-9bcc-43147a8756fc
Customer: somecustomer.com
OrderDetails
Order LineItem: 54 of Blue Widget @unit price: $29.99
Order LineItem: 890 of Red Widget @unit price: $45.89
Total cost of this order: $42461.56
Order status: Pending
Sending back order status information
Klienten visar orderstatusinformationen som skickas av tjänsten.
Press <ENTER> to terminate client.
Status of order 124a1f69-3699-4b16-9bcc-43147a8756fc:Pending
Så här konfigurerar du, skapar och kör exemplet
Kontrollera att du har utfört engångsinstallationsproceduren för Windows Communication Foundation-exempel.
Om du vill skapa C# eller Visual Basic .NET-versionen av lösningen följer du anvisningarna i Skapa Windows Communication Foundation-exempel.
Om du vill köra exemplet i en konfiguration med en eller flera datorer följer du anvisningarna i Köra Windows Communication Foundation-exempel.
Kommentar
Om du använder Svcutil.exe för att återskapa konfigurationen för det här exemplet måste du ändra slutpunktsnamnen i klientkonfigurationen så att de matchar klientkoden.
Som standard NetMsmqBindingär transportsäkerheten aktiverad. Det finns två relevanta egenskaper för MSMQ-transportsäkerhet, MsmqAuthenticationMode och MsmqProtectionLevel.
som standard är autentiseringsläget inställt på Windows
och skyddsnivån är inställd på Sign
. För att MSMQ ska kunna tillhandahålla autentiserings- och signeringsfunktionen måste den vara en del av en domän och active directory-integreringsalternativet för MSMQ måste vara installerat. Om du kör det här exemplet på en dator som inte uppfyller dessa kriterier får du ett fel.
Så här kör du exemplet på en dator som är ansluten till en arbetsgrupp eller utan Active Directory-integrering
Om datorn inte är en del av en domän eller inte har active directory-integrering installerad inaktiverar du transportsäkerheten genom att ställa in autentiseringsläget och skyddsnivån på
None
enligt följande exempelkonfiguration:<configuration> <appSettings> <!-- Use appSetting to configure MSMQ queue name. --> <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderProcessor" /> </appSettings> <system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samples.OrderProcessorService"> <!-- Define NetMsmqEndpoint --> <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="Microsoft.ServiceModel.Samples.IOrderProcessor" /> </service> </services> <bindings> <netMsmqBinding> <binding name="TransactedBinding" > <security mode="None" /> </binding> </netMsmqBinding> </bindings> </system.serviceModel> </configuration>
Om du inaktiverar säkerheten för en klientkonfiguration genereras följande:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <!-- Use appSetting to configure MSMQ queue name. --> <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderStatus" /> </appSettings> <system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samples.OrderStatusService"> <!-- Define NetMsmqEndpoint --> <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderStatus" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="Microsoft.ServiceModel.Samples.IOrderStatus" /> </service> </services> <client> <!-- Define NetMsmqEndpoint --> <endpoint name="OrderProcessorEndpoint" address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="Microsoft.ServiceModel.Samples.IOrderProcessor" /> </client> <bindings> <netMsmqBinding> <binding name="TransactedBinding" > <security mode="None" /> </binding> </netMsmqBinding> </bindings> </system.serviceModel> </configuration>
Tjänsten för det här exemplet skapar en bindning i
OrderProcessorService
. Lägg till en kodrad efter att bindningen har instansierats för att ange säkerhetsläget tillNone
.NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding(); msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
Se till att du ändrar konfigurationen på både servern och klienten innan du kör exemplet.
Kommentar
Inställningen
security mode
tillNone
motsvarar inställningen MsmqAuthenticationModeeller MsmqProtectionLevelMessage
säkerheten förNone
.