Windows Communication Foundation (WCF) を知るその前に
前回の LINQ に引き続き、C#/.NET のお勉強ネタとして取り上げるのは WCF です。
WCF は非常に多くのテクノロジーの集合で、どこから話しを進めようか悩みますね。
MSDNの「Windows Communication Foundation とは」を見てみましょう。
https://msdn.microsoft.com/ja-jp/library/ms731082(v=vs.110).aspx
しょっぱなの書き出しで「WCF は、サービス指向アプリケーションを構築するためのフレームワークです」とあります。まずはサービス指向とはなんちゃら?というところですかね。
オブジェクト指向 → コンポーネント指向 → サービス指向への流れ
一人で開発できる位の規模のちょっとした便利ツールは別として、大抵のシステムは分散アプリケーションです。スマホで動いているアプリも、いろいろなサービスと繋がっています。マテハンは上位システムから仕分け情報が流れてきて、仕分けシステムで整合性をとり、装置制御でさまざまな装置に制御を送っています。お仕事として作るシステムは必ず何らかのサービス同士が連携してエンドユーザーに価値を提供しているのです。
2000年以前はコンポーネント指向でした。機能単位で複数のシステムに配置し、相互接続するためにインターフェース定義言語(IDL)なんかを使って分散アプリケーションを実現しています。マイクロさんの ActiceX/COM/DCOM、旧サンさんの JavaBeans/EJB、IBMさんの CORBA/CCM です。
その後、システムはどんどん肥大化し、多くのシステム同士が連携したり、流れる情報も膨大となりました。機能単位の分散アプリケーションでは立ち行かなくなってきたところでサービス指向というアプローチが登場しました。より本質的に「サービス」という単位で利用者に「価値」を提供するわけです。自然だと思いますよ。使う側も作る側も「機能」って本質ではありませんから。
サービス指向の先駆けは SOAP ですかね。そして REST もサービス指向のお仲間でしょう。WCF は SOAP をベースとしてマイクロさんが持つ様々な分散テクノロジーの集合体となっています。
サービス指向の4原則
マイクロさんがサービス指向の4原則を掲げています。
WCF はこれらを原則を実現するための基盤となります。
-
サービスの境界が明確であること
サービスとサービスを利用する側の境界が明確になっていなければなりません。サービスを公開するには必ずインタフェースなりプロキシを用意します。 -
サービスが自律していること
ブラックボックスのようにサービスを利用するわけですので、サービス自体が自律的に動作できなければなりません。 -
コントラクトを共有すること
コントラクトとは契約です。サービスを提供する側と利用する側でインターフェース情報を共有できなければなりません。コンポーネント指向ではベンダーごとにばらばらで共有できませんでしたから、より中立なスキーマとして Web Services Description Language (WSDL) を使って相互接続します。 -
ポリシーによって互換性を保つこと
コントラクトによってインターフェースを知ることができますが、他にも利用できる通信プロトコル、セキュリティ、信頼性といった制限があります。こういった情報もサービスを利用する側に提供することで互換性を持って接続できるようになります。これらも WSDL で記述します。
この4原則は自分で作るアーキテクチャーにも当てはめたいですね。
せっかく WCF などのアーキテクチャーを利用しても、GUI クラスの中にビジネスロジックがあったり、SQL文がべったり書いてあったり、機器との通信をしているようではいけません。
WCF 以前のアーキテクチャ
マイクロさんはコンポーネント指向の時代から様々なアーキテクチャを提供してきました。
性能要求 | アーキテクチャ | 説明 |
---|---|---|
相互接続 | ASMX(ASP.NET Web Service) | WS-I Basic Profile準拠のWebサービス |
パフォーマンス | COM/DCOM、.NETリモート処理 | バイナリ通信を用いたWindows間の高速通信 |
分散アトミックトランザクション | COM+、Enterprise Services | 分散アトミックトランザクションをサポートする通信 |
非同期メッセージング | MSMQ、System Messasing | 非同期メッセージ、非同期キュー |
セキュリティ | WSE、WS-Security | メッセージの暗号化 |
信頼性 | WSE、WS-Reliable | トランスポートレベルまたはメッセージレベルでの信頼性の保証 |
これまでの開発者は、要件に合わせてこれらを組み合わせてアプリケーションを構築してきました。かなりの深夜残業が続いたことでしょう!
WCF のアーキテクチャ
そんな負担もあって登場したのが WCF です。
MSDN から失敬した WCF のアーキテクチャレイヤーです。
WCF は以前から存在しているアーキテクチャの選択と組み合わせを柔軟に行えるようになります。
既にいろいろなアーキテクチャーを触ったことがある人であれば、この図だけで想像できますかね。これだけの事をXMLの記述と簡単な実装だけで実現できると思うと、わくわくします。
-
コントラクト
サービスを構成するためのコントラクト(契約)を処理します。分散処理に必要な制御を構築します。バインディングは使用するトランスポート (HTTP や TCP など) とエンコーディングを少なくとも指定する必要があります。ポリシーには、セキュリティ要件、およびサービスと通信するために満たす必要があるその他の条件を指定します。 -
サービス ランタイム
サービスの実際の動作が行われます。調整コントロールでは処理するメッセージの数を制限したり、エラー動作では内部エラーが発生したときの振る舞いを指定します。トランザクションの動作では、エラーが発生した場合にロールバックできるようにします。パラメーターのフィルター処理を使用すると、メッセージヘッダーに作用するフィルターに基づいて、事前設定されたアクションを実行できます。 -
メッセージング
メッセージングは、チャネルで構成されます。チャネルの種類としては、トランスポート チャネルとプロトコル チャネルの 2 つがあります。トランスポート チャネルではHTTP、名前付きパイプ、TCP、MSMQ などを指定したりエンコーダを指定します。プロトコル チャネルではメッセージ処理としてWS-Security や WS-Reliability を指定します。 -
ホストとアクティブ化
実行ファイルやサービス、IIS上で動作するためにホストする仕組みまでサポートされています。Windows OS上にWindows アクティブ化サービス (WAS) というのが実は動いていて、WAS を実行しているコンピューター上で WCF アプリケーションを展開すると、自動的にそのアプリケーションをアクティブ化できます。
WCF の ABC
WCF の解説サイトを見ると 通信の3要素としてABCがあると説明されています。語呂がいいんでしょうね。MSDN では見かけませんけど。
A:アドレス(どこへ?)
B:バインド(どのように?)
C:コントラクト(なにを?)
このABCを合わせて、エンドポイントと呼びます。
アドレス
URIによってサービスのアドレスを示します。ベースアドレスは、トランスポート プロトコル+ホスト名+サービス名を示します。エンドポイントの相対アドレスを組み合わせて全体のアドレスが決まります。
トランスポート プロトコル | スキーム |
---|---|
HTTP | http:// または https:// |
TCP | net.tcp:// |
名前付きパイプ | net.pipe:// |
MSMQ | net.msmq:// |
UDP | soap.udp:// |
バインド
どのようにメッセージを送るのか、あるいはメッセージを受けるのかを示します。具体的にはどのようなトランスポート・プロトコルで通信し、どのようなエンコーディングを使用するかなどを設定します。
バインディング名 | 概要 |
---|---|
NetTcpBinding | TCP/IPを使用するバインディング |
BasicHttpBinding | WebサービスのBasic-Profileを使用するバインディング |
WsHttpBinding | Webサービス拡張仕様を使用するバインディング |
WsDualHttpBinding | Webサービス拡張仕様(WS-*)を使用したより高機能なWebサービスによる通信で、しかも非同期双方向通信を行わせる場合に使用 |
NetNamedPipeBinding | 名前付きパイプを使用するバインディング |
NetMsmqBinding | MSMQを使用してWCFコンポーネントと接続するためのバインディング |
MsmqIntegrationBinding | MSMQを使用し、WCFコンポーネントでないMSMQアプリケーションと接続するためのバインディング |
NetPeerTcpBinding | PeerToPerr通信をサポートするバインディング |
WebHttpBinding | WebスタイルのRESTfulをサポートするバインディング |
UdpBinding | UDPを使用するバインディング |
コントラクト
何を交換するのかを意味します。具体的にはほかに公開するサービスは何で(=サービス・コントラクト)、あるいは利用しようとするサービスは何で(=オペレーション・コントラクト)、そして交換するメッセージは何か(=データ・コントラクトもしくはメッセージ・コントラクト)を定義します。
メッセージ・コントラクトで使用可能な型は次のとおりです。
コントラクト | 概要 |
---|---|
プリミティブ型 | 数値・文字列などの.NETの基本データ型は特定の属性を付加することなく、そのまま使用可能 |
Messageクラス | メッセージについての詳細を定義せず、汎用のMessageクラスを使用する方法 |
データ・コントラクト | クラス・インターフェイスのメソッド・プロパティについて属性を付加することでやり取りするデータを指定する方法 |
メッセージ・コントラクト | WCFを介してやり取りするSOAPメッセージの構造を直接定義する方法 |
ビヘイビア
ABCから外れていますが、Behaviorと呼ばれるコンポーネントもあります。ビヘイビアは、サービスやクライアントの動作を実行時に変更または修正する役割を持っています。サービスビヘイビアのスロットリングでは、多数のメッセージが同時に集中したときの対処方法を指定したり、エンドポイントビヘイビアではセキュリティ資格の検索方法を指定したりします。
ビヘイビア | 概要 |
---|---|
CommonBehavior | すべてのエンドポイントにグローバルに作用する |
ServiceBehavior | サービスに関連する部分だけに作用する |
EndpointBehavior | エンドポイントに関連するプロパティのみに作用する |
OperationBehavior | 特例のオペレーションに作用する |
つづく!
備忘録として書き始めたけど、盛り込みすぎました。
全然実装に入れなかったので、次回に続くとします。
WCF って一般的にどれくらい使われているのでしょう?
LINQに引き続き、MSさんはよく作り込んだなーという印象です。Javaでもここまで包括的なアーキテクチャーは少ないかなと。
ちなみに Qiita の 2016/9/30 時点で WCFタグは、記事投稿数は8つ、フォロワーは2人!
MSさんは自身のサービスのために色々な場面で使っていると思うけど、ふつうの技術者は使わないんだろうか?