WCF 4.5 新機能


環境 :
Visual Studio 2012 Beta (.NET Framework 4.5 Beta)

こんにちは。

来たる 2012/04/24 - 04/25 に開催される Windows Developer Days では、 私のセッションでは、WebSocket サーバーの開発技術について解説します。(45 分間です。)
このセッションでは、新しい IIS、ASP.NET、WCF の各技術がベースとなっていて、お時間があれば、ASP.NET や WCF 4.5 のその他の新機能についても紹介したかったのですが、きっと解説している時間はないと思いますので、ここで補足しておきます。(なお、ASP.NET の最新技術については、井上 章や、小野さんが実施するセッションを是非 ご参照ください。)

まず、WCF 4.5 (.NET Framework 4.5 の WCF) の新機能については、既に MSDN に掲載されています。

[MSDN] What's New in Windows Communication Foundation 4.5
http://msdn.microsoft.com/en-us/library/dd456789(v=vs.110).aspx

ここで紹介されている各機能について、以下に、簡単に (First-look で) 解説します。

 

Configuration Intellisense / Configuration ToolTips

WCF でアプリケーション (サービス、クライアント) を構築する場合、構成ファイル (.config ファイル) のデバッグは頭の痛い問題です。WCF 4.5 では、この構成ファイル (.config ファイル) 編集におけるインテリセンス (IntelliSense) やツールチップ (ToolTip) の充実、ビルド時の構成エラーの際の出力結果の強化など、構成ファイルの編集をサポートするさまざまな機能強化がおこなわれています !

細かな解説は省略しますが、以前と比べ かなり編集しやすくなっていますので、是非、実際に Visual Studio 2012 (Beta) を使って、皆さんの手で試してみてください。

 

Simplified Generated Configuration Files

[サービス参照の追加] (Add Service Reference) メニュー (svcutil.exe) によって .config に作成されるクライアント構成の情報も簡素化されています。(以前は、膨大な設定情報を作成したため、メンテナンスが大変でした。)
また、この際に生成されるプロキシー クラス (クライアント側のクラス コード) も、最近のプログラミング環境に配慮し、非同期のメソッド (Async メソッド) が提供されるようになっています。

補足 : WCF 4.5 では、async / await を使って、サーバー サイドの非同期 (async) 処理も実装しやすくなっています。WCF 4.5 を使ったサーバー サイドの async メソッドについては、「ASP.NET WebForms 4.5, WCF 4.5 における非同期 (async) メソッド」の投稿に記載しましたので参照してください。(2012/05 追記)

 

Simplifying Exposing an Endpoint Over HTTPS with IIS

WebMatrix のみならず、WCF の標準のプロジェクトでも、IDE 上のコマンド (下図) によって SSL (https) 用の構成設定が可能です。(これにより、簡単に SSL を使用したデバッグが可能です。)

ご存じの方も多いかと思いますが、Visual Studio 2012 の Web プロジェクトでは、既定で、デバッグ時は IIS Express を使用するようになっています。IIS Express では、ご存じの通り、%userprofile%\Documents\IISExpress\config\applicationhost.config にこうした設定が保存されます。(上記の SSL の設定も、ここに保存されます。)

なお、デバッグ環境として (IIS Express ではなく) IIS を使用する場合、上記の SSL 有効化をおこなう際には、あらかじめ、Web サイトで、SSL (https) が使えるように設定をおこなっておいてください。(方法については、以前 こちら に記載した内容などを参考にしてください。)

 

New Transport Default Values

上記の MSDN のページに記載されている通り、Quotas、Timeout 関連の多くの既定値 (limitation) があがっています。(上記のリンクを参照。) また、XmlDictionaryReaders の既定の Quota もあがっていて、かつ変更可能になっています。
これまでは比較的 低い既定値が設定されていたため、開発途中で、頻繁に上限値に遭遇していたと思いますが、WCF 4.5 からは、こうしたトラブルが軽減されます。

 

Multiple Authentication Support

WCF サービスで、複数の認証スキームをサポートできます。(IIS Host の場合は、IIS (Web サーバー) に設定された複数の認証スキームを使用できます。なお、IIS Host と Self-Host の双方で、この Multiple Authentication Support の設定が可能です。)

例えば、IIS Host の場合、WCF サービスを IIS にホストし、下記の通り、InheritedFromHost を設定します。この設定により、IIS 側の認証スキームにあわせてサービス側でサポートされる認証スキームが変更され、IIS 側で複数の認証を有効 (Enabled) にした場合、WCF 側でもこれら複数の認証が使用できます。(wsdl を見ると、変更されていることが確認できます。)

<system.serviceModel>
  . . .

  <bindings>
    <basicHttpBinding>
      <binding name="testBinding">
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="InheritedFromHost" />
        </security>
      </binding>
    </basicHttpBinding>
  </bindings>
  . . .

</system.serviceModel>

例えば、IIS 側では、下図の通り、Windows 認証と Basic 認証の双方を有効にしておきます。

すると、クライアント作成時に、[サービス参照の追加] (svcutil.exe) によって構成を自動作成すると、下記の通り、Windows 認証が優先的に使用されます。

. . .

<system.serviceModel>
  <bindings>
      <basicHttpBinding>
          <binding name="BasicHttpBinding_IService1">
              <security mode="TransportCredentialOnly">
                  <transport clientCredentialType="Windows" />
              </security>
          </binding>
      </basicHttpBinding>
  </bindings>
  <client>
    <endpoint
      address="http://localhost/WcfService1/Service1.svc"
      binding="basicHttpBinding"
      bindingConfiguration="BasicHttpBinding_IService1"
      contract="ServiceReference1.IService1"
      name="BasicHttpBinding_IService1" />
  </client>
</system.serviceModel>
. . .

サービス側を変更せずに、クライアント側を下記の通り Basic に変更すると、Basic 認証を使用して接続することも可能です。

. . .

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IService1">
                <security mode="TransportCredentialOnly">
                    <transport clientCredentialType="Basic" />
                . . .

サービス側で、上記のように、複数の認証スキームを有効にしている場合には、下記の通り、これら複数の認証に対応したチャレンジ (Challenge) ヘッダーが返されます。
こうして、上述の通り、クライアント側の好みに応じて、異なる認証を扱えるようになっています。

HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
WWW-Authenticate: Basic realm="testmachine"
X-Powered-By: ASP.NET
Date: Mon, 19 Mar 2012 07:21:13 GMT
Content-Length: 6833
Proxy-Support: Session-Based-Authentication

. . .

なお、Self-Host の場合は、下記の通り、使用する認証スキームを authenticationSchemes 属性で指定します。

. . .

<system.serviceModel>
  . . .

  <behaviors>
    <serviceBehaviors>
      <behavior name="testBehavior">
        <serviceAuthenticationManager
          authenticationSchemes="Basic, Ntlm, Negotiate"/>

        . . .

      </behavior>
    </serviceBehaviors>
  </behaviors>
  . . .

 

Compression and the Binary Encoder

レスポンスの圧縮が可能です。
下記の通り、BinaryMessageEncodingBinding の compressionFormat 属性を使って、圧縮のアルゴリズム (Deflate, Gzip) を指定できます。(このため、下記の通り、CustomBinding を使用する必要があります。)

. . .

<system.serviceModel>
  . . .

  <bindings>
    <customBinding>
      <binding name="testBinding">
        <binaryMessageEncoding
          compressionFormat="GZip"/>
        <httpTransport />
      </binding>
    </customBinding>
  </bindings>
  . . .

サービスが返す結果 (Contents の Body) は、下記の通り、gzip に圧縮されます。

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 132
Content-Type: application/soap+msbin1
Content-Encoding: gzip
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 19 Mar 2012 07:54:50 GMT

. . .

 

Streaming Improvements

サービスから複数のクライアントへストリーミング メッセージを送信する際、下記の通り endpointBehavior を構成することで、単一クライアントによるブロック (つまり、処理全体の遅延) を防ぐことができます。

. . .

<system.serviceModel>
  <services>
    <service behaviorConfiguration="testBehavior"
              name="WcfService1.Service1">
      <endpoint address=""
                binding="customBinding"
                behaviorConfiguration="testEndpointBehavior"
                contract="WcfService1.IService1">
      </endpoint>
    </service>
  </services>
  <behaviors>
    <endpointBehaviors>
      <behavior name="testEndpointBehavior">
        <dispatcherSynchronization
          asynchronousSendEnabled="true"/>

      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      . . .

    </serviceBehaviors>
  </behaviors>
  . . .

また逆に、バイナリーのアップロードなど、IIS に Host された WCF サービスにストリーミング送信する際にも、これまでのように、ASP.NET のパイプラインによってバッファされることは無くなり、本当の意味での「ストリーミング」によるアップロードが可能です。

 

IDN (Internationalized Domain Names) Support

Non-Ascii 文字も含むドメイン名に対応しています。IDN を使用する際は、構成ファイル (.config) を使用して、下記の通り有効化します。

<configuration>
  <uri>
    <!-- AllExceptIntranet or All -->
    <idn enabled="AllExceptIntranet"/>
  </uri>
  . . .

 

UDP

これまでも、WCF による WS-Discovery 準拠な ad-hoc discovery サービス (こちら の T2-304 を参照) など、構成によって、内部で UDP は使用されていましたが、WCF 4.5 からは、正式に UDP のマルチ キャストによる「バインディング」 (Binding) が提供されています。

例えば、サービス側を下記の通り実装します。(OneWay なサービスとして実装します。)

. . .

class Program
{
    static void Main(string[] args)
    {
        ServiceHost sv = new ServiceHost(typeof(Service1));
        sv.Open();
        Console.ReadLine();
        sv.Close();
    }
}

[ServiceContract]
public class Service1
{
    [OperationContract(IsOneWay = true)]
    void DoWork(string test)
    {
        Console.WriteLine(test);
    }
}
. . .
. . .

<system.serviceModel>
    <services>
        <service name="UdpApp.Service1">
            <endpoint address=""
                      binding="udpBinding"
                      contract="UdpApp.Service1">
            </endpoint>
            <host>
                <baseAddresses>
                    <add baseAddress="soap.udp://224.0.0.1:9999" />
                </baseAddresses>
            </host>
        </service>
    </services>
</system.serviceModel>
. . .

上記のサービスを複数起動して、下記のクライアントからメッセージ送信をおこなうと、マルチ キャストにより、複数のサービスで同時に要求を受け取ることができます。(途中からサービスを参加させるなどして試してみてください。)

. . .

class Program
{
    static void Main(string[] args)
    {
        using (ChannelFactory<Service1> factory =
            new ChannelFactory<Service1>("MyClientConfig"))
        {
            factory.Open();
            Service1 proxy = factory.CreateChannel();
            while (true)
            {
                proxy.DoWork("aaaaa");
                System.Threading.Thread.Sleep(3000);
            }
            factory.Close();
        }
    }
}

[ServiceContract]
public interface Service1
{
    [OperationContract(IsOneWay = true)]
    void DoWork(string test);
}
. . .
. . .

<system.serviceModel>
  <client>
    <endpoint name="MyClientConfig"
              address="soap.udp://224.0.0.1:9999"
              contract="ConsoleApplication6.Service1"
              binding="udpBinding"/>
  </client>
</system.serviceModel>
. . .

 

Contract-First

svcutl.exe ([サービス参照の追加] メニューを使用した際に内部で使用されるプログラム) に /serviceContract オプションを設定することで、.wsdl ファイルから Contract 定義のコードを逆生成することができます。
Visual Studio 以外のツールなどで wsdl を先に定義して、後からこの定義を元に開発をおこなうことが可能です。

 

そして、WebSocket Support

最新のプラットフォームでは、WCF だけでなく、IIS 8、ASP.NET 4.5 も含む各テクノロジー スタックで、WebSocket をサポートしています。

この内容は、「WebSocket サーバー開発 : WCF 4.5 編」 に記載しました。(2012/04 追記)

 

関連ナンバー

 

Comments (0)

Skip to main content