Obousměrná komunikace
Dvoucestná ukázka ukazuje, jak provést transactovanou obousměrnou komunikaci ve frontě přes MSMQ. Tato ukázka používá netMsmqBinding
vazbu. V tomto případě je služba konzolovou aplikací v místním prostředí, která umožňuje sledovat službu, která přijímá zprávy ve frontě.
Poznámka:
Postup nastavení a pokyny k sestavení pro tuto ukázku najdete na konci tohoto tématu.
Tato ukázka je založená na transactované vazbě MSMQ.
Ve frontě komunikace klient komunikuje se službou pomocí fronty. Klient odesílá zprávy do fronty a služba přijímá zprávy z fronty. Služba a klient proto nemusí být spuštěna ve stejnou dobu, aby komunikovaly pomocí fronty.
Tato ukázka ukazuje 2cestnou komunikaci pomocí front. Klient odešle nákupní objednávky do fronty z rozsahu transakce. Služba obdrží objednávky, zpracuje objednávku a potom zavolá klienta se stavem objednávky z fronty v rámci rozsahu transakce. Pro usnadnění obousměrné komunikace klient a služba používají fronty k zařazení nákupních objednávek a stavu objednávky.
Kontrakt IOrderProcessor
služby definuje jednosměrné operace služby, které vyhovují použití front. Operace služby zahrnuje koncový bod odpovědi, který se má použít k odeslání stavu objednávky. Koncový bod odpovědi je identifikátor URI fronty pro odeslání stavu objednávky zpět klientovi. Aplikace pro zpracování objednávek implementuje tento kontrakt.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po, string
reportOrderStatusTo);
}
Klient určí kontrakt odpovědi na odeslání objednávky. Klient implementuje kontrakt stavu objednávky. Služba používá vygenerovaný proxy server tohoto kontraktu k odeslání stavu objednávky zpět klientovi.
[ServiceContract]
public interface IOrderStatus
{
[OperationContract(IsOneWay = true)]
void OrderStatus(string poNumber, string status);
}
Operace služby zpracuje odeslanou nákupní objednávku. Použije OperationBehaviorAttribute se na operaci služby k určení automatického zařazení v transakci, která se používá k přijetí zprávy z fronty a automatické dokončování transakcí při dokončení operace služby. Třída Orders
zapouzdřuje funkce zpracování objednávek. V tomto případě přidá nákupní objednávku do slovníku. Transakce, ve které je operace služby zařazena, je k dispozici pro operace ve Orders
třídě.
Operace služby kromě zpracování odeslané nákupní objednávky odpoví klientovi na stav objednávky.
[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();
}
Název fronty MSMQ se zadává v části aplikace Nastavení konfiguračního souboru. Koncový bod pro službu je definován v části System.ServiceModel konfiguračního souboru.
Poznámka:
Název fronty MSMQ a adresa koncového bodu používají mírně odlišné konvence adresování. Název fronty MSMQ používá tečku (.) pro místní počítač a oddělovače zpětného lomítka v jeho cestě. Adresa koncového bodu Wcf (Windows Communication Foundation) určuje net.msmq: scheme, používá pro místní počítač "localhost" a v cestě používá lomítka. Pokud chcete číst z fronty hostované na vzdáleném počítači, nahraďte ". a "localhost" názvem vzdáleného počítače.
Služba je hostovaná v místním prostředí. Při použití přenosu MSMQ je nutné předem vytvořit použitou frontu. Můžete to provést ručně nebo prostřednictvím kódu. V této ukázce služba zkontroluje existenci fronty a v případě potřeby ji vytvoří. Název fronty se načte z konfiguračního souboru. Základní adresu používá nástroj ServiceModel Metadata Utility Tool (Svcutil.exe) k vygenerování proxy serveru do služby.
// 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();
}
}
Klient vytvoří transakci. Komunikace s frontou probíhá v rámci transakce, což způsobuje, že se bude považovat za atomické jednotky, kde všechny zprávy proběhnou úspěšně nebo selžou.
// 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();
}
Klientský kód implementuje IOrderStatus
kontrakt pro příjem stavu objednávky ze služby. V tomto případě vytiskne stav objednávky.
[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);
}
}
Fronta stavu objednávky se vytvoří v Main
metodě. Konfigurace klienta zahrnuje konfiguraci služby stavu objednávky pro hostování služby stavu objednávky, jak je znázorněno v následující ukázkové konfiguraci.
<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>
Při spuštění ukázky se aktivity klienta a služeb zobrazí v oknech služby i konzoly klienta. Můžete vidět, že služba přijímá zprávy od klienta. Stisknutím klávesy ENTER v každém okně konzoly vypnete službu a klienta.
Služba zobrazí informace o nákupní objednávce a indikuje, že odesílá zpět stav objednávky do fronty stavu objednávky.
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
Klient zobrazí informace o stavu objednávky odeslané službou.
Press <ENTER> to terminate client.
Status of order 124a1f69-3699-4b16-9bcc-43147a8756fc:Pending
Nastavení, sestavení a spuštění ukázky
Ujistěte se, že jste pro ukázky windows Communication Foundation provedli jednorázovou instalační proceduru.
Pokud chcete sestavit edici C# nebo Visual Basic .NET řešení, postupujte podle pokynů v části Sestavení ukázek windows Communication Foundation.
Pokud chcete spustit ukázku v konfiguraci s jedním nebo více počítači, postupujte podle pokynů v části Spuštění ukázek windows Communication Foundation.
Poznámka:
Pokud použijete Svcutil.exe k opětovnému vygenerování konfigurace pro tuto ukázku, nezapomeňte upravit názvy koncových bodů v konfiguraci klienta tak, aby odpovídaly kódu klienta.
Ve výchozím nastavení NetMsmqBindingje povolené zabezpečení přenosu. Pro zabezpečení MsmqAuthenticationMode přenosu MSMQ existují dvě relevantní vlastnosti a MsmqProtectionLevel.
ve výchozím nastavení je režim ověřování nastavený Windows
na úroveň Sign
ochrany . Aby služba MSMQ poskytovala funkci ověřování a podepisování, musí být součástí domény a musí být nainstalovaná možnost integrace služby Active Directory pro MSMQ. Pokud tuto ukázku spustíte na počítači, který nesplňuje tato kritéria, zobrazí se chyba.
Spuštění ukázky na počítači připojeném k pracovní skupině nebo bez integrace služby Active Directory
Pokud váš počítač není součástí domény nebo nemá nainstalovanou integraci služby Active Directory, vypněte zabezpečení přenosu nastavením režimu ověřování a úrovně ochrany tak, jak
None
je znázorněno v následující ukázkové konfiguraci:<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>
Vypnutí zabezpečení pro konfiguraci klienta vygeneruje následující:
<?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>
Služba pro tuto ukázku vytvoří vazbu v objektu
OrderProcessorService
. Přidejte řádek kódu po vytvoření vazby pro nastavení režimu zabezpečení naNone
.NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding(); msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
Před spuštěním ukázky nezapomeňte změnit konfiguraci na serveru i klientovi.
Poznámka:
Nastavení
security mode
, kteréNone
odpovídá nastavení MsmqAuthenticationMode, MsmqProtectionLevel neboMessage
zabezpečeníNone
pro .