Windows Process Activation Service(以下WAS)を使用してnet.tcp接続のバインディングをホストして見ます。最後に、複数のスキーマ(net.tcp, http)を使用して、複数のサービスをWASでホストできることを確認します。

確認環境

  • Windows Vista Enterprise(サービス,クライアントともに同一)
  • 開発環境:Visual Studio 2008 Professional 英語版
  • 動作環境:IIS7.0, .NET 3.5
  • バインディング:netTcpBinding,basicHttpBinding

参考リンクを掲載しておきます。

-Windows プロセス アクティブ化サービスでのホスティング
http://msdn.microsoft.com/ja-jp/library/ms734677.aspx

1. WASサービスの準備

1.1 WASサービスの有効化

最初に非HTTPバインディングでもWASからWCFサービスをホストできるように確認を行います。Control Panelを開き左下の[Turn AWindows features on or off]を選択します。Windows Features画面で、Microsoft .NET Framework 3.0を展開して、Windows Communication Foundation HTTP Activation, Windows Communication Foundation Non-HTTP Activationにチェックが入っていることを確認します。チェックがない場合は、チェックして[OK]ボタンを押して、WASを有効にしてください。

 

 

1.2 構成ファイルの編集

WASで非HTTPバインドを使用するにはサイトバインドを構成ファイルに設定します。構成ファイルは、%windir%\system32\inetsrv\config\applicationHost.config です。
記事の最初で紹介したリンク,サブリンク先にも書いてありますが、デフォルトで設定されている808ポートを使用したnet.tcpサイトバインドを追加する場合は次のように入力します。

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

 

 

私の環境ではすでに既定のサイト'Default Web Site'に対して、サイトバインディングが構成されていました。構成結果がどうなるかは冒頭のリンク先を参照。

サイトバインドを削除する場合は次のように入力
%windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" --bindings.[protocol='net.tcp',bindingInformation='808:*']

1.3 サービスの起動

記事のはじめに紹介したMSDNのサイトどおりにしても動かなかったので苦労た部分がここです。[スタート]→[Administratuve Tools]→[Services]を選択し、Net.Tcp Listener Adapterサービスが起動していることを確認して下さい。(リンク先にはWASを構成する際に直接的にこのサービスを有効にする記載がなかったため、気付くのに時間がかかりました。)。私の環境ではデフォルトでStatusがdisabledになっています。サービスを開始すると、自動的にポート共有用のサービスNet.Tcp Port Sharing Serviceも開始されます。net.tcp以外で確認していませんが、HTTP以外でWASでWCFサービスを開始する場合は、接続の種類にあわせてNet.Pipe Listener Adapterサービスなどを開始する必要があると思います。

 

 

以上で環境設定は終了です。

2.WCFサービスの作成

2.1 空のソリューションの作成

Visual Studioを起動し、空のソリューションWCFSample020を作成します。

2.2 WCFサービスプロジェクトの作成

ソリューションエクスプローラ上でソリューションを右クリック→[Add]→[New Project]でWCF Service Libraryを選択し、WCFSample.Service.HelloServiceというプロジェクト名で新規作成する。既定で作成されるApp.config,IService1.cs,Service1.csを削除し、IHelloService.cs,HelloService.csファイルを作成し次のように編集する。

以下、IHelloService.cs

namespace WCFSample.Service.HelloService
{
    [ServiceContract]
    public interface IHelloService
    {
        [OperationContract]
        string Hello(string name);
    }
}

以下、HelloService.cs

namespace WCFSample.Service.HelloService
{
    public class HelloService : IHelloService
    {

        #region IHelloService Members

        public string Hello(string name)
        {
            string template = "Hello {0}";
            return string.Format(template, name);
        }

        #endregion
    }
}

3. Webサイトプロジェクトの作成

ソリューションエクスプローラ上でソリューションを右クリック→[Add]→[New Web Site]選択。プロジェクトテンプレートにEmpty Web Siteを選択肢、HelloSiteという名前で作成しました。プロジェクトの参照追加でWCFSample.Service.HelloServiceを追加します。

3.1 service.svcの作成

service.svcファイルを作成し、次のように編集します。

<%@ServiceHost Service="WCFSample.HelloService.ProductService" Language="C#" %>

3.2 構成ファイルの作成

サイトを右クリック→[Add New Item]を選択肢、Web Configuration Fileを選択して、作成。作成されたWeb.configを右クリックしEdit WCF Configurationを選択して、Service Configuration Editorを起動します。
エディタ上の左ペインのCreate a New Serviceを選択して、Wizardを開始し以下のように設定します。

  • Service Type:WCFSample.HelloService.HelloService
  • Contract:WCFSample.HelloService.IHelloService
  • What communication mode is yoru servfice using?画面でTCPを選択
  • Address:ブランク(WASを使用するため)

確認画面が次のように表示されることを確認し、設定を保存して終了します。

 

 

変更が反映されたWeb.configにメタデータ交換用の設定を以下のように設定しておきます。青文字が手編集した部分です。(Service Configuration Editorでも設定可能ですが、ここでは説明を省略します。過去の記事を参照して下さい。)。system.serviceModelないのみ掲載します。

<system.serviceModel>
    <services>
      <service name="WCFSample.Service.HelloService.HelloService" behaviorConfiguration ="was">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration=""
            contract="WCFSample.Service.HelloService.IHelloService" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="was">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata  httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

 3.3 IISにサイトを登録

Administration Toolsから、IIS Managerを起動しDefault Web Siteを右クリック[Add Application]を選択して作成したWebサイトプロジェクトのサイトを登録します(以下は設定例)。

 

 

コマンドプロンプトをAdministrator権限で起動し、次のコマンドを入力して、net.tcp,httpバインディングのサービスをホストできるようにします。コマンドを入力するとhttp,net.tcpを使用するWCFサービスをホストできるようになります。httpも使用可能としたのは、WCFクライアントプロジェクトからサービス参照の追加でプロキシを作成しようとすると、うまく動作しなかったためです。

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

 

 

コマンド入力で設定した値は、IISマネージャ上でHelloSiteを右クリック[Manage Application]→[Advanced Settings..]で表示される、Enabled Protocolsの設定値で確認、変更できます。

 

 

4. WCFクライアントプロジェクト作成

ソリューションを右クリックしコンソールアプリケーションのプロジェクトWCFSample.ConsoleClientを新規作成します。

4.1 プロキシの作成

プロジェクトを右クリック→[Add Service Reference]を選択し、サービス参照を追加します。

 

 

次のようのApp.configが作成されます。net.tcp://localhost/HelloSite/service.svcでサービスに接続できるようになりました。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IHelloService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                    hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                    maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
                    maxReceivedMessageSize="65536">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Transport">
                        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://localhost/HelloSite/service.svc" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IHelloService" contract="Proxy.IHelloService"
                name="NetTcpBinding_IHelloService">
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

4.2プログラムの作成

Program.csを次のように編集し、動作確認をして終了です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCFSample.ConsoleClient.Proxy;

namespace WCFSample.ConsoleClient
{
    class Program
    {
        static void Main(string[] args)
        {
            HelloServiceClient proxy = new HelloServiceClient("BasicHttpBinding_IHelloService");
            Console.WriteLine(proxy.Hello("WCF 日本語書籍販売"));
            proxy.Close();
            Console.ReadLine();
        }
    }
}

クライアントプロジェクトをスタートアッププロジェクトに設定してデバッグ実行すると次のように表示され、サービスが呼び出されたことが確認できます。

 

 

5. httpBasicBindingを追加してみる

同じアドレス,ポート番号で異なるバインディングをホストできます。(netstat -aコマンドで簡単な形で確認できますが、net.tcpは実際には808番のポートを介してサービスが実行されます。)httpを使用したホストもできるように設定したので、basicHttpBindingを追加してみます。

HelloSiteプロジェクトのWeb.configに次のエンドポイントを追加します。(青色部分が変更箇所)

<system.serviceModel>
    <services>
      <service name="WCFSample.Service.HelloService.HelloService" behaviorConfiguration ="was">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
            contract="WCFSample.Service.HelloService.IHelloService" />
        <endpoint address="" binding="netTcpBinding" bindingConfiguration=""
            contract="WCFSample.Service.HelloService.IHelloService" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="was">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata  httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

WCFSample.ConsoleClientのApp.configも対応するクライアントのエンドポイントを作成します。変更箇所のみ青色で記載しています。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IHelloService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                    hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                    maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
                    maxReceivedMessageSize="65536">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Transport">
                        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://localhost/HelloSite/service.svc" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IHelloService" contract="Proxy.IHelloService"
                name="NetTcpBinding_IHelloService">
            </endpoint>
          <endpoint address="http://localhost/HelloSite/service.svc" binding="basicHttpBinding"
              bindingConfiguration="" contract="Proxy.IHelloService"
              name="BasicHttpBinding_IHelloService">
          </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Program.csでバインディングに使用するエンドポイントを変更して、動作することを確認します。変更箇所は青色で記載しています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCFSample.ConsoleClient.Proxy;

namespace WCFSample.ConsoleClient
{
    class Program
    {
        static void Main(string[] args)
        {
            HelloServiceClient proxy = new HelloServiceClient("BasicHttpBinding_IHelloService");
            Console.WriteLine(proxy.Hello("WCF 日本語書籍販売"));
            proxy.Close();
            Console.ReadLine();
        }
    }
}

 動作確認をすると、http://localhost/HelloSite/service.svcをエンドポイントのアドレスとしてサービスに接続できることが確認できます。

 以上で完了です。不明点、誤りなどありましたら、ご連絡くださいませ。