WCFの拡張?
開発手順は、先にサービス提供側を開発してから、クライアント側を開発するながれだと思う。
先にサービス側開発しないと、クライアントの開発ほぼ不可能の状態となる。
もしかしたら、サービス側で提供する機能のメソッドを宣言して置いて(実際の機能を実装しない)、一回発行してクライアント側の実装は、宣言したものによって、開発しやすくなると思う。
IISによって、サービスの提供は Visual Studio の 「Web」-「WCF サービス アプリケーション」テンプレートのプロジェクトを作成して、
これはサービス提供側のWEB端末となります。
作成したWEB端末にWCFサービスライブラリを追加するのは、Visual Studio の WCF から「WCFサービスライブラリ」テンプレートを利用して、
プロジェクトを作成する。
作成したWCFサービスライブラリプロジェクト、ディフォルトでは、IService1.cs と Service1.cs 二つファイルが追加されている。
これは、WCFサービス提供側のひなとなります。
何のプロジェクトでも構いません。Windows From 、Console、WPFなど
サービスを提供できるように、いくつやらないといけないことがあります。
例:
internal static ServiceHost myServiceHost = null;
サービス開始
Uri baseAddress = new Uri("http://localhost:8080/MemberService"); myServiceHost = new ServiceHost(typeof(SampleService),baseAddress); myServiceHost.Open(); serviceButton.Text = "Stop Service";
サービス停止
if (myServiceHost.State != CommunicationState.Closed) { myServiceHost.Close(); serviceButton.Text = "Start Service"; }
クライアントでは、何のプロジェクトでも構いません。Windows Form、Console、WPFなど
前提条件:サービス提供側を構築した状態。
svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config http://192.168.11.2:8080/Service.svcまだ svcutil コマンドの使い方として、下記のような方法があります。
svcutil WCFSample.LongTimeService.dllメタファイルからプロキシを作成する
svcutil /namespace:*,WCFSample.Client handcraft.wcfsample.org.2008.05.17.wsdl *.xsd /out:Proxy.cs
「サービス参照の追加」によって、ソリューションに追加されたものからみて、判断した。
「IXXXService」
サービス側提供しているメソッドのインターフェイス。
インターフェイスの属性は[ServiceContract()]となります。
「XXXService」
「IXXXService」インターフェイスを実装したサービスクラス。
※具体的に、もっと活用的にこのクラスの中に何を実装すればいいかはっきり分からないが、一応インターフェイスの実装しなければならない。
「Member」クラス
これはデータのコンテナクラスとなります。
クラスの属性は[DataContract]となり、クラス中の各プロパティの属性は[DataMember]となります。
WCFサービスクラスはデフォルトではクライアントとのセッションが維持されます。つまり、クライアントの接続があると、対応する1つのサービスクラスのインスタンスが作成されます。つまり1000クライアントから同時接続されると、1000ものインスタンスが作成されます。これはサービスクラスに付与する ServiceBehavor.InstanceContextMode のデフォルト値がInstanceContextMode.PerSessionとなっているためです。InstanceContextModeの種類は次のとおり
PerSession | ServiceBehavior のデフォルト値.各セッション(クライアントから接続があるたび)に、新しくインスタンスが作成されます。 OperationBehavior.ReleaseInstanceModeを指定しない限り、クライアントのプロキシを閉じると、インスタンスが破棄されます。 |
PerCall | クライアントがサービスメソッドを呼び出すたびに、新しくインスタンスが作成されます。このモードではセッションごとにインスタンスが作成されないので、スケーラビリティが改善されます。ただし、状態を維持する必要がある場合は、独自で状態管理の方法を実装する必要があります。 |
Single | サービスクラスの1つのインスタンスのみ作成されます。複数のクライアントが接続しても、サービスクラスのインスタンスは1つのみとなります。このインスタンスはWCFのホストプログラムが停止したときのみ破棄されます。 |
以下のようにサービスクラスのServiceBehaviorAttributeで指定します。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] public class ProductService : IProductService {....}
ServiceBehavior.InstanceContextModeをInstanceContextMode.Single とすると、同時に複数のクライアントがサービスメソッドを呼び出しても同時に1つの要求のみが処理されます。そのため、多くのクライアントからリクエストを受けるとタイムアウトが大量に発生する可能性があります。これを避ける場合のひとつの方法として、 ServiceBehavior.ConcurrencyModeをSingle(デフォルト)からMultiple にすることで、複数のリクエストを同時に処理できるようになります。ただし、スレッドセーフではなくなるので、同期が必要な処理はサービスクラスの定義者が実装する必要があります。ServiceConcurrencyMode.Reentrantはサービスクラス自身はシングルスレッドで実行されますが、サービスクラス内で別のサービスを呼び出し、呼び出し先の別サービスからコールバックメソッドを呼び出すことができるようにするモードです。
OperationBehavior.ReleaseInstanceModeにReleaseInstanceMode.None以外の値を設定することで、インスタンスの生存期間をコントロールできます。ServiceBehavior.ContextModeがPerSessionのときに組み合わせて使用すると効果があります。
AfterCall | サービスメソッド呼び出し後にインスタンスを破棄する。 |
BeforeCall | サービスメソッド呼び出し前に既存のインスタンスを破棄し、新しいインスタンスを作成する。 |
BeforeAndAfterCall | サービスメソッド呼び出し前に新しいインスタンスを作成し、呼び出し後にインスタンスを破棄する。 |
None | デフォルトの値。インスタンスの破棄はServiceBehavior.InstanceContextModeにより決定される。 |
ServiceContract.SessionMode, OperationContract.IsInitiating, OperationContract.IsTerminatingを使用して、サービスメソッドの呼び出し順(開始、途中、最後)を強制できるようになります。上述のプロパティはWCFに特化した処理であり、WCF以外のクライアントとの互換性に影響が発生します。詳細内容はMSDNを参照して下さい。
WCFのサービス側で throw new FaultException() すると、その例外はクライアント側に通知されるようになっている。クライアント側でも catch(FaultException e) で受け取り。
更に FaultException<T> というジェネリックも定義されていて、 FaultException に俺クラスの情報を付与して例外発生できる。というか受け側で catch(FaultException<T> e) によって選別できるのがうれしい。ただし、これを実現するためのプロキシクラス作成には svcutil コマンドを利用する必要がある。 WSDL 経由では例外に関するメタデータが公開されないようだ。
コメント:
0