前に作ったコードをベースに新たにサーバーを起こしてみたり。
.NETになって「.NETリモート処理」なるものが実装されました。
結構お手軽なのですが、ここで問題になるのが「クライアントにもリモート処理可能オブジェクト(DLL)」が必要なこと。
これは、コンパイル時に型を参照する為ばかりでなく、実行時にも必要です。
せっかくサーバ側とクライアント側を分離したはずなのに、リモート処理可能オブジェクトと共にサーバ側だけでしか必要の無いDLL等が必要なことを意味します。
また、クライアント側に実装の詳細が見えてしまいかねません。
これの解決策は、MSDNのNET Framework開発者ガイドに記載がありますが、
「別のライブラリでインターフェイスを宣言し、そのライブラリをクライアントと共に配置する方法。」
です。
でも、こんな方法もあるということで。
(一応、VB.NET 2003~2008まで使えています)
1)サーバーソリューションを作り、クラスライブラリのプロジェクトを作ります。
クラスライブラリプロジェクト内に下記のようにインタフェースだけを定義したクラスを作ります。
コンパイルすると、インタフェースクラスライブラリのDLLが出来上がります。
2)サーバソリューション内にそのライブラリを参照したサーバープロジェクトを作ります。Public MustInherit Class ServerObject Inherits MarshalByRefObject Public MustOverride Function Func1(ByVal param) as Integer End Class
サーバープロジェクト内に、インタフェースから派生したクラスとオブジェクトを登録するモジュールを作ります。
これらは同一実行モジュール内におくことが出来ます。
ポイントは、
RemotingConfiguration.RegisterWellKnownServiceType()
で登録するオブジェクトは、インタフェースクラスでなく、派生クラスの物を登録することです。3)クライアントは、別のソリューションを作ります。Imports System Imports System.Threading Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Http Public Class Server Inherits ServerObject Public Overrides Function Func1(ByVal param) as Integer Return param * 10 ' とリあえず簡単なもの^^; End Function End Class Module mdlMain Sub Main() Dim channel As HttpChannel = New HttpChannel(30000) ChannelServices.RegisterChannel(channel) ' サービスタイプを登録 RemotingConfiguration.RegisterWellKnownServiceType(GetType(Server), _ "Server", WellKnownObjectMode.SingleCall) ' ウィンドウが閉じられるまで待機 Dim sync As Object = New Object SyncLock sync Monitor.Wait(sync) End SyncLock End Sub End Module
先にサーバーで作成したインタフェースを定義したライブラリプロジェクトを追加し、(既存のプロジェクトの追加)
新たにクライアント本体のプロジェクトを作ります。
そして、以下のようにクライアントプロジェクトを記述します。
ポイントは、
Activator.GetObject()
でインタフェースのオブジェクトを取得するように記述することです。これで、クライアント側には、クライアントモジュールEXEとインタフェースDLLのみ配置すれば実行することができます。Module mdlMain Sub Main() ' HTTPチャンネルを登録 Dim chan as New HttpChannel ChannelServices.RegisterChannel(chan) ' GetTypeの引数 = "インタフェースDLLの名前空間.クラス名, インタフェースDLLのアセンブリ名" ← 混乱しやすいので注意!!! Dim obj as Object = Activator.GetObject(Type.GetType("SvrObj.ServerObject, SvrObj"), _ "http://localhost:30000/Server") If Not (obj Is Nothing) Then Dim svr As ServerObject = CType(obj, ServerObject) Dim i as integer i = svr.Func1(10) Console.WriteLine("Server answer = " + i.ToString()) Else Console.WriteLine("Object nothing.") End If End Sub End Module
欠点は、全てのインタフェースAPIを
MustOverride
で定義しなければいけないことでしょうか。【注意事項】ここに掲載されている内容について引用流用は自由ですが、内容やサンプルに基づくいかなる結果に関して一切の責任を負いません。自己の責任の上でご活用ください。