.NET remotingとdRuby

[ .NET Framework Ruby ]

最近.NET Frameworkをいじり始めました。

.NETはVisualStudio .NETがなくても、無料の.NET Framework SDK(と適当なエディタ)だけで開発できるのな。不覚にも知らなかったです。とある事情で、まずは.NET remotingまわりを調査してます。

MSDNだとこのへんから辿れば必要な情報にたどり着けるでしょう。


.NET remoting概要


.NET remotingは、アプリケーション境界・マシン境界を超えた先にあるオブジェクトを透過的に使う仕組みです。C#で.NET remotingは、ちょっと試す分にはとても簡単です。

MarshalByRefObjectを継承したクラスを定義する

これでこのオブジェクトは、アプリケーションドメインを超えて参照渡しできるようになります。
(.NET CLRにはアプリケーションドメインとコンテキストって概念があるみたいだけどまだよく理解してない)

サーバ側とクライアント側に、XMLっぽい構成ファイルを置く

サーバ側は公開するオブジェクト名と公開するURL、クライアント側はアクセスするオブジェクトとそのURLを書きます。通信方法(tcpでバイナリデータ、httpでSOAP)やリモートオブジェクトの生成方法も指定できます(「アクティベーションの方法」という用語が使われてます)。

サーバ側は構成ファイルを読み込んで、ただ起動してればよい

構成ファイルを読み込むメソッドを呼び出して、ただwaitしていれば、リモートオブジェクトへの要求を受け付けるサーバのできあがり。

クライアント側は構成ファイルを読み込んで、リモートオブジェクトをnewする

newするだけでリモートオブジェクトが使えるようになるのだ。実際にリモートオブジェクトが生成されるのは、インスタンスメソッドが呼び出されたときのようです。

とまあこんな感じで、とっかかりは簡単です。

参照渡しと値渡し

さて、起動できるだけじゃだめで、リモートオブジェクトとクライアントの間ではなんらかの情報をやりとりしないといけません。それはメソッドの引数だったり戻り値だったりするわけです。

これらの値もアプリケーションドメイン境界を超えるわけですから、次のいずれかをしないといけません。

  1. MarshalByRefObjectを継承する
  2. serializableにしとく

1.であれば参照渡しになります。2.を行えば値渡しになります。どちらもやらないと、実行時例外になります。両方やると参照渡しになります(MarshalByRefObject自体はserializableになってます)。

とっかかりは簡単だったのに、この辺でもうめんどくさい感が漂ってきます。ぜんぜん透過的じゃないじゃん。リモートから使えるかどうか意識しなきゃだめじゃん。処理系がやってくれればいいじゃん。

まあこのくらいは、最小限のおまじないと思って我慢しないといけないのかな。もし構文上は完全にローカルなオブジェクトと同じように扱えても、リモートオブジェクトかどうかは結局意識しないといけない場面があるでしょうし。

インタフェース

次にひっかかるのが、サーバとなるリモートオブジェクトの型です。

これはクライアントとサーバのインタフェースですから、Interfaceで定義したくなっても不思議じゃありません。

ところがInterfaceで定義しても、クライアント側では具象型を指定しないとリモートオブジェクトを取り出せないみたいです。そのあとInterfaceにキャストして使ってもいいわけですが、そもそも取り出すときは型知らないとダメだってのがちょっといやです。

C#(とCLR)の仕様を考えれば仕方ないかな。

リモートオブジェクトをInterfaceで定義して、クライアント側ではオブジェクトの取り出しの時以外はInterfaceとして扱う、という実装はもちろんできますが。

dRubyだとどうなのさ

型がダイナミックなrubyでのリモート処理にはdRubyってのがあります。ちょっと調べてみたのですが、上記2点の問題については次のことがわかりました

値渡しと参照渡し

rubyそのものと同じく参照渡しのみ。どうしても値渡ししたかったら、オブジェクトをdupする(てかこれは値渡しじゃなくて、コピーの参照渡しですな)。実際に通信路にはどんなデータが乗ってるのかは未調査でよくわかりません。

インタフェース

そもそもrubyにはインタフェースがないです。というか型が動的です。サーバとなるリモートオブジェクトを使うクライアントにとって重要なのはその型ではなくて、送ったメッセージに反応できるかどうかってことだけ。

rubyなのでリモートの型とたとえば「リンク」しとく必要もなく、クライアント側をそのままでサーバ側オブジェクトをぜんぜん違う型にしちゃってもOK。同じメッセージに反応しさえすればいいのですな。

トラックバック

このエントリーのトラックバックURL:
http://www.skoji.jp/mtbin/mt-tb.cgi/428

コメント

>ところがInterfaceで定義しても、クライアント側では具象型を指定しないとリモートオブジェクトを取り出せないみたいです。

ちょっとこんなに遅くコメントするのはなんですが(^^;
普通にだいじょうぶでしたが。。。
.NET Framework のバージョンちがい?(こちらはver 2.0, 1.1でも大丈夫だったような気もしますが。)

ex.
ITest test = (ITest)Activator.GetObject(typeof(ITest),
"http://test:8000/test");

はじめまして、すごく遅いコメントですみません。
dRubyでは、基本は値渡しみたいです。(それだけです、すみません。)

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)