方法: WAS で WCF サービスをホストする

ここでは、Windows プロセス アクティブ化サービス (WAS) でホストされる Windows Communication Foundation (WCF) サービスを作成するために必要な基本的手順を説明します。 WAS は、HTTP 以外のトランスポート プロトコルで動作するインターネット インフォメーション サービス (IIS) 機能を一般化した新しいプロセス アクティブ化サービスです。 WCF では、リスナー アダプター インターフェイスを使用して、WCF でサポートされる HTTP 以外のプロトコル (TCP、名前付きパイプ、メッセージ キューなど) を介して受信されるアクティブ化要求を伝達します。

このホスト オプションでは、WAS アクティブ化コンポーネントのインストールと構成が正しく行われている必要がありますが、アプリケーションの一部としてホスト コードを記述する必要はありません。 WAS のインストールと構成の詳細については、「方法: WCF アクティブ化コンポーネントをインストールして設定する」を参照してください。

警告

Web サーバーの要求処理パイプラインをクラシック モードに設定すると、WAS のアクティブ化がサポートされません。 WAS のアクティブ化を使用する場合は、Web サーバーの要求処理パイプラインを統合モードに設定する必要があります。

WCF サービスが WAS でホストされている場合、標準バインディングは通常の方法で使用されます。 ただし、WAS でホストされるサービスを NetTcpBindingNetNamedPipeBinding を使用して構成する場合は、制限を遵守する必要があります。 つまり、異なるエンドポイントが同じトランスポートを使用する場合、次の 7 つのプロパティでバインディング設定が一致する必要があります。

  • ConnectionBufferSize

  • ChannelInitializationTimeout

  • MaxPendingConnections

  • MaxOutputDelay

  • MaxPendingAccepts

  • ConnectionPoolSettings.IdleTimeout

  • ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint

バインディングの設定が一致しない場合、これらのプロパティの値は常に最初に初期化されたエンドポイントによって決定されるため、後で追加されるエンドポイントは ServiceActivationException をスローします。

この例のソースのコピーについては、「TCP のアクティブ化」を参照してください。

WAS でホストされる基本サービスを作成するには

  1. サービスの種類にサービス コントラクトを定義します。

    [ServiceContract]
    public interface ICalculator
    {
       [OperationContract]
       double Add(double n1, double n2);
       [OperationContract]
       double Subtract(double n1, double n2);
       [OperationContract]
       double Multiply(double n1, double n2);
       [OperationContract]
       double Divide(double n1, double n2);
    }
    
    
  2. サービス クラスにサービス コントラクトを実装します。 アドレス情報とバインディング情報はサービスの実装内では指定されないことに注意してください。 同様に、コードは構成ファイルから情報を取得する必要はありません。

    public class CalculatorService : ICalculator
    {
       public double Add(double n1, double n2)
       {
          return n1 + n2;
       }
       public double Subtract(double n1, double n2)
       {
          return n1 - n2;
       }
       public double Multiply(double n1, double n2)
       {
          return n1 * n2;
       }
       public double Divide(double n1, double n2)
       {
          return n1 / n2;
       }
    }
    
    
  3. NetTcpBinding エンドポイントによって使用される CalculatorService バインディングを定義する Web.config ファイルを作成します。

    <?xml version="1.0" encoding="utf-8" ?>  
    <configuration>  
      <system.serviceModel>  
        <bindings>  
          <netTcpBinding>  
            <binding portSharingEnabled="true">  
              <security mode="None" />  
            </binding>  
          </netTcpBinding>  
        </bindings>  
      </system.serviceModel>  
    </configuration>  
    
  4. 次のコードを含む Service.svc ファイルを作成します。

    <%@ServiceHost language=c# Service="CalculatorService" %>
    
  5. IIS 仮想ディレクトリに Service.svc ファイルを配置します。

サービスを使用するクライアントを作成するには

  1. コマンドラインから ServiceModel Metadata Utility Tool (Svcutil.exe) を使用して、サービス メタデータからコードを生成します。

    Svcutil.exe <service's Metadata Exchange (MEX) address or HTTP GET address>
    
  2. 生成されたクライアントには、クライアントの実装時に満たされなければならないサービス コントラクトを定義する ICalculator インターフェイスが含まれます。

    //Generated interface defining the ICalculator contract	
    [System.ServiceModel.ServiceContractAttribute(
    Namespace="http://Microsoft.ServiceModel.Samples", ConfigurationName="Microsoft.ServiceModel.Samples.ICalculator")]
    public interface ICalculator
    {
    
        [System.ServiceModel.OperationContractAttribute(
    Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")]
        double Add(double n1, double n2);
    
            [System.ServiceModel.OperationContractAttribute(
    Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")]
        double Subtract(double n1, double n2);
    
            [System.ServiceModel.OperationContractAttribute(
    Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")]
        double Multiply(double n1, double n2);
    
            [System.ServiceModel.OperationContractAttribute(
    Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")]
        double Divide(double n1, double n2);
    }
    
  3. 生成されたクライアント アプリケーションは ClientCalculator も実装します。 このサービスの実装では、アドレス情報とバインディング情報が指定されないことに注意してください。 同様に、コードは構成ファイルから情報を取得する必要はありません。

    // Implementation of the CalculatorClient
    public partial class CalculatorClient : System.ServiceModel.ClientBase<Microsoft.ServiceModel.Samples.ICalculator>, Microsoft.ServiceModel.Samples.ICalculator
    {
    
        public CalculatorClient()
        {
        }
    
        public CalculatorClient(string endpointConfigurationName) :
                base(endpointConfigurationName)
        {
        }
    
        public CalculatorClient(string endpointConfigurationName, string remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {
        }
    
        public CalculatorClient(string endpointConfigurationName,
                System.ServiceModel.EndpointAddress remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {
        }
    
        public CalculatorClient(System.ServiceModel.Channels.Binding binding, 				System.ServiceModel.EndpointAddress remoteAddress) :
                base(binding, remoteAddress)
        {
        }
    
        public double Add(double n1, double n2)
        {
            return base.Channel.Add(n1, n2);
        }
    
        public double Subtract(double n1, double n2)
        {
            return base.Channel.Subtract(n1, n2);
        }
    
        public double Multiply(double n1, double n2)
        {
            return base.Channel.Multiply(n1, n2);
        }
    
        public double Divide(double n1, double n2)
        {
            return base.Channel.Divide(n1, n2);
        }
    }
    
  4. NetTcpBinding を使用するクライアントの構成は、Svcutil.exe で生成することもできます。 Visual Studio を使用する場合は、このファイルの名前は App.config ファイル内で指定する必要があります。

    
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel> 
            <bindings> 
                <netTcpBinding> 
                    <binding name="NetTcpBinding_ICalculator"> 
                        <security mode="None"/> 
                    </binding> 
                </netTcpBinding> 
            </bindings> 
            <client> 
                <endpoint 
                  address="net.tcp://localhost/servicemodelsamples/service.svc" 
                  binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ICalculator" 
                  contract="ICalculator" name="NetTcpBinding_ICalculator" /> 
            </client>
        </system.serviceModel> 
    </configuration>
    
    
  5. アプリケーションで ClientCalculator のインスタンスを作成し、サービス操作を呼び出します。

    //Client implementation code.
    class Client
    {
        static void Main()
        {
            // Create a client with given client endpoint configuration
            CalculatorClient client = new CalculatorClient();
    
            // Call the Add service operation.
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
            // Call the Subtract service operation.
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
    
            // Call the Multiply service operation.
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
    
            // Call the Divide service operation.
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
    
            //Closing the client gracefully closes the connection and cleans up resources
            client.Close();
    
            Console.WriteLine();
            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();
        }
    }
    
  6. クライアントをコンパイルして実行します。

関連項目