Two-Way サンプルでは、MSMQ 経由でトランザクション双方向のキュー通信を実行する方法を示します。 このサンプルでは、 netMsmqBinding
バインドを使用します。 この場合、サービスはセルフホステッド コンソール アプリケーションであり、キューに登録されたメッセージを受信しているサービスを監視できます。
注
このサンプルのセットアップ手順とビルド手順は、このトピックの最後にあります。
このサンプルは、 Transacted 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>
サンプルを実行すると、クライアントとサービスのアクティビティが、サービスとクライアントの両方のコンソール ウィンドウに表示されます。 サービスがクライアントからメッセージを受信しているのを確認できます。 各コンソール ウィンドウで Enter キーを押して、サービスとクライアントをシャットダウンします。
サービスは発注書情報を表示し、注文ステータスを注文ステータスキューに返送していることを示します。
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
サンプルを設定、ビルド、実行するには
Windows Communication Foundation サンプル のOne-Time セットアップ手順を実行していることを確認します。
ソリューションの C# または Visual Basic .NET エディションをビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。
単一または複数のコンピューター間の構成でサンプルを実行するには、「Windows Communication Foundation Samplesの実行」の手順に従います。
注
Svcutil.exe を使用してこのサンプルの構成を再生成する場合は、クライアント構成のエンドポイント名をクライアント コードと一致するように変更してください。
既定では、 NetMsmqBindingではトランスポート セキュリティが有効になっています。 MSMQ トランスポート セキュリティには、 MsmqAuthenticationMode と MsmqProtectionLevel.
の 2 つの関連プロパティがあります。既定では、認証モードは Windows
に設定され、保護レベルは Sign
に設定されます。 MSMQ で認証と署名機能を提供するには、ドメインの一部である必要があり、MSMQ の Active Directory 統合オプションをインストールする必要があります。 これらの条件を満たしていないコンピューターでこのサンプルを実行すると、エラーが発生します。
ワークグループに参加しているコンピューター、または 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
に設定することと同じです。