次の方法で共有


MSMQ のアクティブ化

MsmqActivation サンプルでは、メッセージ キューから読み取られたアプリケーションを Windows プロセス アクティブ化サービス (WAS) でホストする方法を示します。 このサンプルでは、 netMsmqBinding を使用し、 Two-Way Communication サンプルに基づいています。 この場合のサービスは Web でホストされるアプリケーションであり、クライアントはセルフホステッドであり、送信された発注書の状態を確認するためにコンソールに出力されます。

このサンプルのセットアップ手順とビルド手順は、このトピックの最後にあります。

Windows Server 2008 の新しいプロセス アクティブ化メカニズムである Windows プロセス ライセンス認証サービス (WAS) は、以前は HTTP ベースのアプリケーションでのみ使用できる IIS のような機能を、HTTP 以外のプロトコルを使用するアプリケーションに提供します。 Windows Communication Foundation (WCF) は、リスナー アダプター インターフェイスを使用して、TCP、名前付きパイプ、MSMQ など、WCF でサポートされている HTTP 以外のプロトコルを介して受信したアクティブ化要求を通信します。 HTTP 以外のプロトコル経由で要求を受信する機能は、SMSvcHost.exeで実行されているマネージド Windows サービスによってホストされます。

Net.Msmq リスナー アダプター サービス (NetMsmqActivator) は、キュー内のメッセージに基づいてキューに登録されたアプリケーションをアクティブにします。

クライアントは、トランザクションのスコープ内からサービスに発注書を送信します。 サービスはトランザクション内の注文を受け取り、処理します。 その後、サービスは注文の状態でクライアントを呼び出します。 双方向通信を容易にするために、クライアントとサービスの両方でキューを使用して、発注書と注文の状態をエンキューします。

サービス コントラクト 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 クラスの操作で使用できます。

サービス操作では、送信された発注書の処理に加えて、注文の状態に関する応答がクライアントに返されます。

public class OrderProcessorService : IOrderProcessor
{
    [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();
        msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
        OrderStatusClient client = new OrderStatusClient(msmqCallbackBinding, new EndpointAddress(reportOrderStatusTo));
        // please note that the same transaction that is used to dequeue purchase order is used
        // to send back order status
        using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
        {
            client.OrderStatus(po.PONumber, po.Status);
            scope.Complete();
        }
    }
}

使用するクライアント バインドは、構成ファイルを使用して指定します。

MSMQ キュー名は、構成ファイルの appSettings セクションで指定されます。 サービスのエンドポイントは、構成ファイルの System.serviceModel セクションで定義されます。

MSMQ キュー名とエンドポイント アドレスでは、アドレス指定規則が若干異なります。 MSMQ キュー名は、ローカル コンピューター用にドット (.) を使用し、キュー名のパスには円記号を区切り記号として使用します。 WCF エンドポイント アドレスでは、net.msmq: スキームを指定し、ローカル コンピューターを表すのに "localhost" を使用し、そのパスにはスラッシュを使用します。 リモート コンピューターでホストされているキューから読み取る場合は、"." と "localhost" をリモート コンピューター名に置き換えます。

クラスの名前を持つ .svc ファイルは、WAS でサービス コードをホストするために使用されます。

Service.svc ファイル自体には、 OrderProcessorServiceを作成するためのディレクティブが含まれています。

<%@ServiceHost language="c#" Debug="true" Service="Microsoft.ServiceModel.Samples.OrderProcessorService"%>

Service.svc ファイルには、System.Transactions.dll が読み込まれるようにするためのアセンブリ ディレクティブも含まれています。

<%@Assembly name="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"%>

クライアントはトランザクション スコープを作成します。 サービスとの通信はトランザクションのスコープ内で行われ、すべてのメッセージが成功または失敗するアトミック単位として扱われます。 トランザクションは、トランザクション スコープで Complete を呼び出すことによってコミットされます。

using (ServiceHost serviceHost = new ServiceHost(typeof(OrderStatusService)))
{
    // Open the ServiceHostBase to create listeners and start listening
    // for order status messages.
    serviceHost.Open();

    // Create a proxy with given client endpoint configuration
    OrderProcessorClient client = new OrderProcessorClient();

    // Create the purchase order
    PurchaseOrder po = new PurchaseOrder();
    po.CustomerId = "somecustomer.com";
    po.PONumber = Guid.NewGuid().ToString();

    PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
    lineItem1.ProductId = "Blue Widget";
    lineItem1.Quantity = 54;
    lineItem1.UnitCost = 29.99F;

    PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
    lineItem2.ProductId = "Red Widget";
    lineItem2.Quantity = 890;
    lineItem2.UnitCost = 45.89F;

    po.orderLineItems = new PurchaseOrderLineItem[2];
    po.orderLineItems[0] = lineItem1;
    po.orderLineItems[1] = lineItem2;

    //Create a transaction scope.
    using (TransactionScope scope = new
        TransactionScope(TransactionScopeOption.Required))
    {
        // Make a queued call to submit the purchase order
        client.SubmitPurchaseOrder(po,
       "net.msmq://localhost/private/ServiceModelSamplesOrder/OrderStatus");
        // Complete the transaction.
        scope.Complete();
    }

    //Closing the client gracefully closes the connection and cleans up
    //resources
    client.Close();

    Console.WriteLine();
    Console.WriteLine("Press <ENTER> to terminate client.");
    Console.ReadLine();

    // Close the ServiceHostBase 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="targetQueueName" value=".\private$\ServiceModelSamples/service.svc" />
    <add key="responseQueueName" value=".\private$\ServiceModelSamples/OrderStatus" />
  </appSettings>

<system.serviceModel>

    <services>
      <service
         name="Microsoft.ServiceModel.Samples.OrderStatusService">
        <!-- Define NetMsmqEndpoint -->
        <endpoint address="net.msmq://localhost/private/ServiceModelSamples/OrderStatus"
                  binding="netMsmqBinding"
                  contract="Microsoft.ServiceModel.Samples.IOrderStatus" />
      </service>
    </services>

    <client>
      <!-- Define NetMsmqEndpoint -->
      <endpoint name="OrderProcessorEndpoint"
                address="net.msmq://localhost/private/ServiceModelSamples/service.svc"
                binding="netMsmqBinding"
                contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
    </client>

  </system.serviceModel>

サンプルを実行すると、クライアントとサービスのアクティビティがサーバーとクライアントの両方のコンソール ウィンドウに表示されます。 サーバーがクライアントからメッセージを受信しているのを確認できます。 各コンソール ウィンドウで Enter キーを押して、サーバーとクライアントをシャットダウンします。

クライアントは、サーバーによって送信された注文状態情報を表示します。

Press <ENTER> to terminate client.
Status of order 70cf9d63-3dfa-4e69-81c2-23aa4478ebed :Pending

サンプルを設定、ビルド、実行するには

  1. WAS ライセンス認証に必要であるため、IIS 7.0 がインストールされていることを確認します。

  2. Windows Communication Foundation サンプル One-Time セットアップ手順を実行していることを確認します。 さらに、WCF 非 HTTP アクティブ化コンポーネントをインストールする必要があります。

    1. [スタート] メニューの [コントロール パネル] を選択します。

    2. [ プログラムと機能] を選択します。

    3. [ Windows の機能をオンまたはオフにする] をクリックします。

    4. [ 機能の概要] で、[ 機能の追加] をクリックします。

    5. Microsoft .NET Framework 3.0 ノードを展開し、Windows Communication Foundation の非 HTTP アクティブ化機能を確認します。

  3. ソリューションの C# または Visual Basic .NET エディションをビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。

  4. コマンド ウィンドウから client.exe を実行して、クライアントを実行します。 これにより、キューが作成され、メッセージが送信されます。 クライアントを実行したままにして、サービスがメッセージを読み取った結果を確認します

  5. MSMQ アクティブ化サービスは、既定でネットワーク サービスとして実行されます。 そのため、アプリケーションのアクティブ化に使用されるキューには、Network Service の受信およびピークアクセス許可が必要です。 これは、メッセージ キュー MMC を使用して追加できます。

    1. [スタート] メニューの [実行] をクリックし、「Compmgmt.msc」と入力して Enter キーを押します。

    2. [ サービスとアプリケーション] で、[ メッセージ キュー] を展開します。

    3. プライベート キュー をクリックします。

    4. キュー (servicemodelsamples/Service.svc) を右クリックし、[プロパティ] を選択 します

    5. [ セキュリティ ] タブで、[ 追加 ] をクリックし、ネットワーク サービスに対するピークと受信のアクセス許可を付与します。

  6. MSMQ ライセンス認証をサポートするように Windows プロセス ライセンス認証サービス (WAS) を構成します。

    便宜上、次の手順は、サンプル ディレクトリにある AddMsmqSiteBinding.cmd という名前のバッチ ファイルに実装されます。

    1. net.msmq のアクティブ化をサポートするには、既定の Web サイトを最初に net.msmq プロトコルにバインドする必要があります。 これは、IIS 7.0 管理ツールセットと共にインストールされている appcmd.exeを使用して行うことができます。 管理者特権コマンド プロンプトから、次のコマンドを実行します。

      %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site"
      -+bindings.[protocol='net.msmq',bindingInformation='localhost']
      

      このコマンドは 1 行のテキストです。

      このコマンドは、net.msmq サイト バインドを既定の Web サイトに追加します。

    2. サイト内のすべてのアプリケーションは共通の net.msmq バインドを共有しますが、各アプリケーションで net.msmq のサポートを個別に有効にすることができます。 /servicemodelsamples アプリケーションで net.msmq を有効にするには、管理者特権のコマンド プロンプトから次のコマンドを実行します。

      %windir%\system32\inetsrv\appcmd.exe set app "Default Web Site/servicemodelsamples" /enabledProtocols:http,net.msmq
      

      このコマンドは 1 行のテキストです。

      このコマンドを使用すると、 http://localhost/servicemodelsamplesnet.msmq://localhost/servicemodelsamplesを使用して/servicemodelsamples アプリケーションにアクセスできます。

  7. 以前に行っていない場合は、MSMQ アクティブ化サービスが有効になっていることを確認します。 [スタート] メニューの [実行] をクリックし、「Services.msc」と入力します。 Net.Msmq リスナー アダプターのサービスの一覧を検索します。 右クリックし、[プロパティ] を選択します。 [スタートアップの種類] を [自動] に設定し、[適用] をクリックして [スタート] ボタンをクリックします。 この手順は、Net.Msmq リスナー アダプター サービスを最初に使用する前に 1 回だけ実行する必要があります。

  8. シングル コンピューター構成またはクロスコンピューター構成でサンプルを実行するには、「 Windows Communication Foundation サンプルの実行」の手順に従います。 さらに、発注書を送信するときに、キューの URI にコンピューター名を反映するように、注文書を送信するクライアントのコードを変更します。 次のコードを使用します。

    client.SubmitPurchaseOrder(po, "net.msmq://localhost/private/ServiceModelSamples/OrderStatus");
    
  9. このサンプル用に追加した net.msmq サイト バインドを削除します。

    便宜上、次の手順は、サンプル ディレクトリにある RemoveMsmqSiteBinding.cmd という名前のバッチ ファイルに実装されます。

    1. 管理者特権でのコマンド プロンプトから次のコマンドを実行して、有効なプロトコルの一覧から net.msmq を削除します。

      %windir%\system32\inetsrv\appcmd.exe set app "Default Web Site/servicemodelsamples" /enabledProtocols:http
      

      このコマンドは 1 行のテキストです。

    2. 管理者特権でのコマンド プロンプトから次のコマンドを実行して、net.msmq サイト バインドを削除します。

      %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" --bindings.[protocol='net.msmq',bindingInformation='localhost']
      

      このコマンドは 1 行のテキストです。

    Warnung

    バッチ ファイルを実行すると、.NET Framework バージョン 2.0 を使用して実行するように DefaultAppPool がリセットされます。

既定では、 netMsmqBinding バインディング トランスポートでは、セキュリティが有効になっています。 トランスポート セキュリティの種類は、 MsmqAuthenticationModeMsmqProtectionLevelの 2 つのプロパティによって決まります。 既定では、認証モードは Windows に設定され、保護レベルは Sign に設定されます。 MSMQ で認証と署名機能を提供するには、ドメインの一部である必要があります。 ドメインに含まれていないコンピューターでこのサンプルを実行すると、"ユーザーの内部メッセージ キュー証明書が存在しません" というエラーが表示されます。

ワークグループに参加しているコンピューターでサンプルを実行するには

  1. コンピューターがドメインの一部でない場合は、次のサンプル構成に示すように、認証モードと保護レベルを none に設定してトランスポート セキュリティをオフにします。

    <bindings>
        <netMsmqBinding>
            <binding configurationName="TransactedBinding">
                <security mode="None"/>
            </binding>
        </netMsmqBinding>
    </bindings>
    
  2. サンプルを実行する前に、サーバーとクライアントの両方で構成を変更します。

    security modeNone に設定することは、MsmqAuthenticationModeMsmqProtectionLevelMessageセキュリティをNoneに設定することと同じです。

  3. ワークグループに参加しているコンピューターでライセンス認証を有効にするには、アクティブ化サービスとワーカー プロセスの両方を特定のユーザー アカウントで実行する必要があり (両方で同じである必要があります)、キューには特定のユーザー アカウントの ACL が必要です。

    ワーカー プロセスが実行される ID を変更するには

    1. Inetmgr.exeを実行します。

    2. [ アプリケーション プール] で、 AppPool (通常 は DefaultAppPool) を右クリックし、[ アプリケーション プールの既定値の設定]を選択します

    3. 特定のユーザー アカウントを使用するように ID プロパティを変更します。

    アクティブ化サービスが実行される ID を変更するには:

    1. Services.msc を実行します。

    2. Net.MsmqListener アダプターを右クリックし、[プロパティ] を選択します。

  4. [LogOn] タブでアカウントを変更します。

  5. ワークグループでは、サービスも無制限のトークンを使用して実行する必要があります。 これを行うには、コマンド ウィンドウで次を実行します。

    sc sidtype netmsmqactivator unrestricted
    

こちらも参照ください