Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
В примереTwo-Way показано, как выполнять транзакционный двусторонний обмен данными в очереди через MSMQ. В этом примере используется привязка netMsmqBinding . В этом случае служба — это локальное консольное приложение, которое позволяет наблюдать за службой, получающей сообщения в очереди.
Замечание
Процедура установки и инструкции по сборке для этого примера находятся в конце этого раздела.
Этот пример основан на передаваемой привязке MSMQ.
Клиент взаимодействует со службой через очередь сообщений. Клиент отправляет сообщения в очередь, а служба получает сообщения из очереди. Таким образом, службе и клиенту не нужно запускаться одновременно, чтобы взаимодействовать через очередь.
В этом примере показана двусторонняя связь с помощью очередей. Клиент отправляет заказы на закупку в очередь в рамках транзакции. Служба получает заказы, обрабатывает их, а затем перезванивает клиенту с информацией о состоянии заказа из очереди в рамках транзакции. Чтобы облегчить двустороннюю связь, клиент и служба используют очереди для постановки заказов на покупку и статусов заказа.
Контракт IOrderProcessor обслуживания определяет односторонние операции обслуживания, подходящие для использования очередей. Операция службы включает конечную точку ответа, которую используют для отправки статусов заказа. Конечная точка ответа — это URI очереди для отправки состояния заказа обратно клиенту. Приложение обработки заказов реализует этот контракт.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po, string
reportOrderStatusTo);
}
Контракт ответа для отправки статуса заказа указывается клиентом. Клиент реализует контракт состояния заказа. Служба использует созданный прокси-сервер этого контракта для отправки состояния заказа клиенту.
[ServiceContract]
public interface IOrderStatus
{
[OperationContract(IsOneWay = true)]
void OrderStatus(string poNumber, string status);
}
Операция службы обрабатывает отправленный заказ на покупку.
OperationBehaviorAttribute применяется к операции службы, чтобы указать на автоматическое участие в транзакции, которая используется для получения сообщения из очереди, и автоматическое завершение транзакции при завершении операции службы. Класс Orders инкапсулирует функции обработки заказов. В этом случае он добавляет заказ на покупку в словарь. Транзакция, в которую включена операция службы, доступна операциям в Orders классе.
Операция службы, помимо обработки отправленного заказа на покупку, возвращает клиенту ответы на состояние заказа.
[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 указывается в разделе appSettings файла конфигурации. Конечная точка службы определена в разделе System.ServiceModel файла конфигурации.
Замечание
Имя очереди MSMQ и адрес конечной точки используют несколько разные соглашения об адресации. Имя очереди MSMQ использует точку (.) для локального компьютера и обратную косую черту в пути. Адрес конечной точки Windows Communication Foundation (WCF) задает схему net.msmq, использует localhost для локального компьютера и использует косую черту в пути. Чтобы прочитать из очереди, размещенной на удаленном компьютере, замените "." и "localhost" на название удаленного компьютера.
Служба размещена на собственных серверах. Очередь, используемую для транспорта MSMQ, необходимо создавать заранее. Это можно сделать вручную или с помощью кода. В этом примере служба проверяет наличие очереди и создает ее при необходимости. Имя очереди считывается из файла конфигурации. Базовый адрес используется средством служебной программы метаданных ServiceModel (Svcutil.exe) для создания прокси-сервера в службе.
// 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();
}
}
Клиент создает транзакцию. Обмен данными с очередью выполняется в пределах транзакции, вследствие чего она рассматривается как атомарная единица, в которой все сообщения либо завершаются успешно, либо терпят неудачу.
// 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();
}
Клиентский IOrderStatus код реализует контракт для получения состояния заказа от службы. В этом случае он выводит состояние заказа.
[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);
}
}
Очередь состояния заказа создается в методе Main . Конфигурация клиента включает конфигурацию службы состояния заказа для размещения службы состояния заказа, как показано в следующем примере конфигурации.
<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>
При запуске примера действия клиента и службы отображаются как в окнах службы, так и в консоли клиента. Вы можете увидеть, как служба получает сообщения от клиента. Нажмите клавишу ВВОД в каждом окне консоли, чтобы завершить работу службы и клиента.
Служба отображает информацию о заказе на покупку и указывает, что она отправляет статус заказа обратно в очередь состояния заказов.
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
Клиент отображает сведения о состоянии заказа, отправленные службой.
Press <ENTER> to terminate client.
Status of order 124a1f69-3699-4b16-9bcc-43147a8756fc:Pending
Настройка, сборка и запуск примера
Убедитесь, что вы выполнили процедуру настройки One-Time для образцов Windows Communication Foundation.
Чтобы создать версию решения на C# или Visual Basic .NET, следуйте инструкциям по сборке примеров Windows Communication Foundation .
Чтобы запустить пример в конфигурации с одним или несколькими компьютерами, следуйте инструкциям в запуска примеров Windows Communication Foundation.
Замечание
Если вы используете Svcutil.exe для повторного создания конфигурации для этого примера, обязательно измените имена конечных точек в конфигурации клиента, чтобы соответствовать коду клиента.
По умолчанию в NetMsmqBindingвключена транспортная безопасность. Существует два важных свойства для безопасности транспорта MSMQ: MsmqAuthenticationMode и MsmqProtectionLevel.. По умолчанию режим проверки подлинности установлен на Windows, а уровень защиты - на Sign. Чтобы MSMQ предоставляла функцию проверки подлинности и подписывания, она должна быть частью домена, а параметр интеграции Active Directory для MSMQ должен быть установлен. Если запустить этот пример на компьютере, который не соответствует этим критериям, вы получите ошибку.
Запуск примера на компьютере, присоединенном к рабочей группе или без интеграции Active Directory
Если ваш компьютер не входит в домен или если интеграция с Active Directory не установлена, можно отключить транспортную безопасность, задавая режим проверки подлинности и уровень защиты на
None, как показано в следующем примере конфигурации.<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>Отключение безопасности для конфигурации клиента приводит к следующему:
<?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>Служба для этого примера создает привязку в объекте
OrderProcessorService. Добавьте строку кода после создания экземпляра привязки, чтобы задать для режима безопасности значениеNone.NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding(); msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;Перед запуском примера убедитесь, что вы измените конфигурацию как на сервере, так и на клиенте.
Замечание
Установка
security modeнаNoneэквивалентна установке безопасности MsmqAuthenticationMode, MsmqProtectionLevel илиMessageнаNone.