自分磨きのITノート

プログラミング(C#、VB.NET)言語やデータベースの役立つ情報を初心者から中級者向けに発信します。

WCF

WCFサービスの単体テスト方法(デバッグ)

WCFサービスアプリケーションのホスト(サーバー)側の単体デバックについてです。

クライアントアプリケーションを作成せずに単体テストするには、VisualStudioのツールである「WcfTestClient.exe」使用することになると思います。色々な引数を与えてテストすることができるので便利です。

「***.svc」のファイルを選択した状態でデバックの開始を行うと以下のようなツールが立ち上がります。
※ SVCファイルを選択してないとブラウザが立ち上がります(最後に対処法説明)・・・20180127_wcftestclient_1
①左ツリーのテストしたいメソッドをダブルクリックします。
②要求の引数の値フィールドに値を入れます。
③「起動」ボタンを押します。
④下の応答に結果が返ります。

通信の中身の確認

下にあるXMLタブを押すと、実際に通信で使用されてSOAPの内容が確認できます。20180127_wcftestclient_xml

XMLの確認で通信量などを把握できます。

引数が配列の場合


続きを読む

WCFは初回が遅い

WCFは便利なライブラリですが、少し気になるのが「初回が遅い」ところです。
一度繋がってしまえば、気にならないくらいの速度なのですが・・・。しかし、その辺をエンドユーザに気づかれないように作りこむのもプログラマーの宿命!(笑)

遅くなってしまう部分は以下の通りです。

①WCFのチャンネル生成しているところ
②WCFで初回メソッドを呼ぶところ

①WCFのチャンネル生成しているところ

ChannelFactory.CreateChannel()を呼び出すあたりで、System.ServiceModel関連のライブラリをロードしているのに時間がかかっているようです。

以下の方も書かれているように、何度もチャンネルを作成するのはコストがかかるみたいです。
http://tnakamura.hatenablog.com/entry/20090804/wcf_channel_cost

無駄なチャンネルはCloseさせたほうがよいのですが、私はチャンネルオブジェクトをメンバ変数に保持して使いまわしています。(問題がある場合は別の方法を推奨します)

m_wcf = factory.CreateChannel(); // グローバルに格納


②WCFで初回メソッドを呼ぶところ

クライアントからメソッドをコールする時です。
ホスト側のリソース作成に時間がかかっていると思われます。セッション作成などに必要な準備をしているのでしょう。また、Webサービス(IISなど)で構築している場合は、サーバへアクセスするまでのコストも考えられるでしょう。

私は初回にデータ量のすくないメソッドなどを起動時コールして逃げています。
データベースアクセスのADO.NETなどの通信もそうですが、初回はどうしてもリソースの確保に時間がかかるので、それを知ったうえで遅さを隠蔽するように作れたらよいですね。

VB.NETのWCF実装サンプル(プロセス間通信編)

インターネットでWCFを検索していると、C#のサンプルが非常に多いですが、VB.NETのサンプルが少なかったのでアップしておきます。ソースコードはC#で記述されている諸先輩サイト様達から参考にさせて頂いてます。


まずは、ホストの実装からです。

ホスト(サーバー)の実装

インターフェース部分

ABCでいうCのコントラクトの部分になります。
<System.ServiceModel.ServiceContract>
Public Interface IMyService
   <System.ServiceModel.OperationContract>
   Function GetData(user_nm As String) As String
End Interface
WCFでやり取りするインターフェースには、ServiceContract属性をつけます。また、メソッドには、OperationContract属性をつけます。
ここでは記述していませんが、独自のクラスデータに場合は、DataContract属性をつけます。

サービス実装部分

Public Class MyService1
   Implements HellowWcfLib.IMyService
    ''' GetDataの実装部分'
    Public Function GetData(user_nm As String) As String Implements HellowWcfLib.IMyService.GetData
      Return "ようこそ、" & user_nm & "さん!WCFの世界へ"
   End Function
End Class
上記で宣言したインターフェースを継承して、メソッド内の処理を作成します。

Configファイルの作成

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="NewBinding0" />
            </basicHttpBinding>
        </bindings>
        <services>
            <!--<service name="HellowWcfService">
                <endpoint binding="netNamedPipeBinding" contract="HellowWcfLib.IMyService" />
            </service>-->
          <service name="HellowWcfService">
            <endpoint binding="netTcpBinding" contract="HellowWcfLib.IMyService" />
          </service>
        </services>
    </system.serviceModel>
</configuration>
Serviceタグ内にbinding方法とコントラクトの名前を記述しています。
今回はTCP通信の実装になります。

サービスの開始と終了

Imports System.ServiceModel
Module Program
   ''' プログラムエントリ'
   Public Sub Main()
      'Dim addr As String = "net.pipe://127.0.0.1/myservice"'
      Dim addr As String = "net.tcp://127.0.0.1:8080/myservice"

      Using serviceHost As ServiceHost = New ServiceHost(GetType(MyService1))
         '// サービス追加(型とバインディング)'
         'serviceHost.AddServiceEndpoint(GetType(HellowWcfLib.IMyService),'
         '                               New NetNamedPipeBinding(),'
         '                               addr)'
         serviceHost.AddServiceEndpoint(GetType(HellowWcfLib.IMyService),
                                        New NetTcpBinding,
                                        addr)
         '/* サービスの開始 *'
         Call serviceHost.Open()
         Console.WriteLine("WCF Service start-->" & addr)
         Console.WriteLine("サービスを終了するときは何かキーを押す")
         '/* 待ち */'
         Dim str As String = Console.ReadLine()
         '/* サービスの終了 */'
         Call serviceHost.Close()

      End Using

   End Sub

End Module
ServiceHostに実装したサービスを指定します。
そして決定したアドレスでサービスをオープンさせます。非同期で受付が開始されます。
Bindingの引数にセキュリティがありますが、クライアントと一致させておく必要があります。

次にクライアント側です。

クライアント側の実装

続きを読む

.Netでプロセス間/端末間/サーバ間通信するならWCFが便利

WCFとは

Windows Communication Foundationの略であり、Microsoftが提供する通信基盤です。
(.Net framework3.0より使用できます)

Webサービス標準のSOAPに準拠しXMLでやり取りが行われ、プロトコルを意識せず通信が行えます。
よく利用されるデータベースにアクセスするためのADO.NETもSOAP通信ですね。
今まではソケット通信だと敷居が高かったり、プロトコル(やり取り)の仕様を考えるのに労力がいりましたが、通信自体はWCFが自動でデータをシリアライズ化してやり取りしてくれます。
利用者は、メソッドをコールするような感覚で通信プログラムが作成できます。

また、サービスがマルチスレッドを管理してくれるので実装も非常に楽です。
メッセージは文字や数値以外に、配列や独自クラスを送ったり受け取ったりできるので色々な場面で使用できると思います。

Webサービス(http通信)だけでなく、プロセス間通信(名前付きパイプ)やPC間通信(TCP)も可能です。
、私もWCFを利用するようになり、こんな便利なライブラリがあるなら早くから試しておけばよかったと思っています。

20180118_wcf_image

続きを読む
Amazon
自己紹介
【管理人】
なみやん
【コメント】
プログラムを組むことが大好きな30代男性。IT系の仕事を10年ちょいやっています。このブログを通して知識を人に伝えることによって、自分をさらに磨こうと精進しています。応援よろしくお願いします。
免責事項
当サイトで紹介しているサンプルソースコードは自由に使用いただいても結構が、自己責任でお使いください。また、記事の内容が主観的であったり、努力していますが正しくなかったりする場合がございます。読者本人の判断にお任せいたします。