Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W przykładzieTwo-Way pokazano, jak przeprowadzić dwukierunkową komunikację w kolejce za pośrednictwem usługi MSMQ. W tym przykładzie użyto netMsmqBinding
wiązania. W takim przypadku usługa jest aplikacją konsolową działającą lokalnie, która umożliwia monitorowanie odbierania komunikatów w kolejce przez usługę.
Uwaga / Notatka
Procedura instalacji i instrukcje kompilacji dla tego przykładu znajdują się na końcu tego tematu.
Niniejszy przykład jest oparty na Transacted MSMQ Binding.
W komunikacji w kolejce klient komunikuje się z usługą za pomocą kolejki. Klient wysyła komunikaty do kolejki, a usługa odbiera komunikaty z kolejki. W związku z tym usługa i klient nie muszą być uruchomione jednocześnie, aby komunikować się przy użyciu kolejki.
W tym przykładzie pokazano komunikację dwukierunkową przy użyciu kolejek. Klient wysyła zamówienia zakupu do kolejki w ramach transakcji. Usługa odbiera zamówienia, przetwarza je, a następnie informuje klienta o stanie zamówienia z kolejki w ramach transakcji. W celu ułatwienia dwukierunkowej komunikacji klient i usługa używają kolejek do kolejkowania zamówień i stanu zamówienia.
Kontrakt IOrderProcessor
na usługę definiuje jednokierunkowe operacje serwisowe, które dobrze pasują do zastosowania kolejkowania. Operacja usługi obejmuje punkt końcowy odpowiedzi, który ma być używany do wysyłania stanów zamówienia. Punkt końcowy odpowiedzi to URI kolejki, za pomocą którego stan zamówienia jest wysyłany z powrotem do klienta. Aplikacja przetwarzania zamówień implementuje ten kontrakt.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po, string
reportOrderStatusTo);
}
Kontrakt dotyczący wysyłania odpowiedzi na status zamówienia jest określany przez klienta. Klient implementuje kontrakt stanu zamówienia. Usługa używa wygenerowanego proxy umowy do wysyłania statusu zamówienia do klienta.
[ServiceContract]
public interface IOrderStatus
{
[OperationContract(IsOneWay = true)]
void OrderStatus(string poNumber, string status);
}
Operacja usługi przetwarza przesłane zamówienie zakupu. Element OperationBehaviorAttribute jest stosowany do operacji usługi w celu określenia automatycznej rejestracji w transakcji używanej do odbierania komunikatu z kolejki i automatycznego uzupełniania transakcji po zakończeniu operacji usługi. Klasa Orders
hermetyzuje funkcje przetwarzania zamówień. W tym przypadku dodaje zlecenie zakupu do słownika. Transakcja, w której znajduje się operacja usługi, jest dostępna dla operacji w klasie Orders
.
Proces usługowy, oprócz przetwarzania przesłanego zamówienia zakupu, odpowiada klientowi na temat statusu zamówienia.
[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();
}
Nazwa kolejki MSMQ jest określona w sekcji appSettings pliku konfiguracji. Punkt końcowy usługi jest zdefiniowany w sekcji System.ServiceModel pliku konfiguracji.
Uwaga / Notatka
Nazwa kolejki MSMQ i adres punktu końcowego używają nieco różnych konwencji adresowania. Nazwa kolejki MSMQ używa kropki (.) dla maszyny lokalnej i separatorów ukośników odwrotnych w ścieżce. Adres punktu końcowego Windows Communication Foundation (WCF) określa schemat net.msmq:, używa "localhost" dla maszyny lokalnej i używa ukośników prostych w ścieżce. Aby odczytać z kolejki hostowanej na maszynie zdalnej, zamień "." i "localhost" na nazwę maszyny zdalnej.
Usługa jest hostowana samodzielnie. W przypadku korzystania z transportu MSMQ kolejka, z której się korzysta, musi zostać utworzona z wyprzedzeniem. Można to zrobić ręcznie lub za pomocą kodu. W tym przykładzie usługa sprawdza istnienie kolejki i tworzy ją w razie potrzeby. Nazwa kolejki jest odczytywana z pliku konfiguracji. Adres podstawowy jest używany przez narzędzie ServiceModel Metadata Tool (Svcutil.exe) do wygenerowania serwera proxy do usługi.
// 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 tworzy transakcję. Komunikacja z kolejką odbywa się w ramach transakcji, co powoduje, że jest ona traktowana jako jednostka atomowa, w której wszystkie komunikaty albo kończą się powodzeniem, albo niepowodzeniem.
// 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();
}
Kod klienta implementuje kontrakt IOrderStatus
w celu otrzymania z usługi stanu zamówienia. W takim przypadku wyświetla stan zamówienia.
[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);
}
}
Kolejka stanu zamówienia jest tworzona w metodzie Main
. Konfiguracja klienta obejmuje konfigurację usługi stanu zamówienia do hostowania usługi stanu zamówienia, jak pokazano w poniższej przykładowej konfiguracji.
<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>
Po uruchomieniu przykładu, działania klienta i usługi są zaprezentowane zarówno w oknach konsoli usługi, jak i klienta. Możesz zobaczyć, jak usługa odbiera komunikaty od klienta. Naciśnij ENTER w każdym oknie konsoli, aby zamknąć usługę i klienta.
Usługa wyświetla informacje o zamówieniu zakupu i wskazuje, że wysyła stan zamówienia z powrotem do kolejki stanu zamówienia.
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 wyświetla informacje o stanie zamówienia wysyłane przez usługę.
Press <ENTER> to terminate client.
Status of order 124a1f69-3699-4b16-9bcc-43147a8756fc:Pending
Aby skonfigurować, skompilować i uruchomić przykładowy program
Upewnij się, że wykonano procedurę instalacji One-Time dla przykładów programu Windows Communication Foundation.
Aby skompilować wersję rozwiązania w języku C# lub Visual Basic .NET, postępuj zgodnie z instrukcjami w Kompilowanie przykładów Windows Communication Foundation.
Aby uruchomić przykład w konfiguracji pojedynczej lub między maszynami, postępuj zgodnie z instrukcjami w Uruchamianie przykładów programu Windows Communication Foundation.
Uwaga / Notatka
Jeśli używasz Svcutil.exe do ponownego wygenerowania konfiguracji dla tego przykładu, pamiętaj o zmodyfikowaniu nazw punktów końcowych w konfiguracji klienta w celu dopasowania ich do kodu klienta.
Domyślnie w systemie NetMsmqBindingsą włączone zabezpieczenia transportu. Istnieją dwie istotne właściwości zabezpieczeń transportu MSMQ, MsmqAuthenticationMode a MsmqProtectionLevel.
domyślnie tryb uwierzytelniania jest ustawiony na Windows
, a poziom ochrony jest ustawiony na Sign
. Aby usługa MSMQ zapewniała funkcję uwierzytelniania i podpisywania, musi być częścią domeny, a opcja integracji usługi Active Directory dla usługi MSMQ musi być zainstalowana. Jeśli uruchomisz ten przykład na komputerze, który nie spełnia tych kryteriów, zostanie wyświetlony błąd.
Aby uruchomić przykład na komputerze przyłączonym do grupy roboczej lub bez integracji z usługą Active Directory
Jeśli komputer nie jest częścią domeny lub nie ma zainstalowanej integracji z usługą Active Directory, wyłącz zabezpieczenia transportu, ustawiając tryb uwierzytelniania i poziom ochrony, tak
None
jak pokazano w następującej przykładowej konfiguracji:<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>
Wyłączenie zabezpieczeń dla konfiguracji klienta generuje następujące elementy:
<?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>
Usługa dla tego przykładu tworzy powiązanie w pliku
OrderProcessorService
. Dodaj wiersz kodu po utworzeniu wystąpienia powiązania, aby ustawić tryb zabezpieczeń naNone
.NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding(); msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
Przed uruchomieniem przykładu upewnij się, że zmienisz konfigurację zarówno na serwerze, jak i na kliencie.
Uwaga / Notatka
Ustawienie
security mode
toNone
jest równoważne ustawieniu MsmqAuthenticationMode, MsmqProtectionLevel lubMessage
naNone
.