DOBON.NET DOBON.NETプログラミング掲示板過去ログ

.NET Remotingのサーバーオブジェクトについて

環境/言語:[C#2.0]
分類:[.NET]

お世話になっております。

http://support.microsoft.com/kb/307600/ja
こちらの記事を参考に.NET Remotingを触っているのですが
動作について判らない事がありましたので質問させて頂きます。

※そのままのソースではセキュリティ警告がでて動かないので
http://msdn.microsoft.com/ja-jp/library/5dxse167%28VS.80%29.aspx
コチラを参考に修正を行ないました。

サーバー側からクライアントオブジェクトを操作したいと思い
サーバー側にもサーバーオブジェクトのインスタンスを作成したのですが
サーバー側のインスタンスとクライアント側のインスタンスは
直接の関係が無いらしくサーバー側から
クライアントオブジェクトのインスタンスは操作出来ませんでした。

そこで
http://codezine.jp/article/detail/530
こちらを参考にサーバー側のインスタンスにも
Activator.GetObjectメソッドで作ったインスタンスを入れる事で
サーバー/クライアント双方の操作が可能になりました。

しかし、
http://moto-square.com/knowledge/dotNet/dotNetRemoting.html
こちらのサンプルソースを実行すると
サーバー側でnewしただけのインスタンスを介して
データのやりとりが出来ているようです。

違いは一体なんなのでしょうか。
ご教授のほどよろしくお願いします。
■No27090に返信(すのうさんの記事)
> サーバー側でnewしただけのインスタンスを介して
> データのやりとりが出来ているようです。

「new しただけ」がどのような意味合いなのか、どのようなものと比較したのかがわかりづらいです。

new するだけでなく、RegisterWellKnownServiceType を利用していること、クライアント側では Activator.GetObject などで取得していることはどちらも同じです。
サンプル自体はダウンロードしていないので、記事に載っていないところで差があるのかもしれませんが…。
■No27090に返信(すのうさんの記事)
> http://moto-square.com/knowledge/dotNet/dotNetRemoting.html
> こちらのサンプルソースを実行すると

その moto-square のサンプル(DotNetRemotingTester.zip)を見ましたが、
> サーバー側からクライアントオブジェクトを操作したいと思い
にはなっていないように見えます。むしろ方向が逆となっており、
クライアントからサーバーにメッセージを送出するサンプルかと。

同ページにも書かれていますが、そもそも .NET Remoting においては
『クライアントからサーバが保持しているオブジェクトに対してアクセスを行う』
というスタイルが基本となります。

ある意味では、Web サイトを閲覧する時の動作に似ているかも知れません。
クライアント(ブラウザー)が、サーバー(Web サイト)にリクエストを
発行することはできますが、その逆に、サーバーの側からクライアント側に
リクエストを開始することはできないという意味で。

> サーバー側でnewしただけのインスタンスを介して
> データのやりとりが出来ているようです。
moto-square のサンプルで言えば、「サーバが保持しているオブジェクト」に
相当するのは、RemotingCommon.dll にて定義された RemotingCommon です。

まず、サーバー側(RemotingServer.exe) の動作を見てみると、
RemotingServer クラスの RegisterChannel メソッド内で
RemotingCommon オブジェクトのインスタンスを保持しており、
それを任意のチャンネル(IPC とか TCP とか HTTP とか)で公開しています。

一方、クライアント側(RemotingClient.exe) については、
RemotingClient クラスの RegisterChannel メソッド内において、
上記で事前に開かれたチャンネルを通じて、
公開された RemotingCommon クラスを受け取っています。

あとは、RemotingCommon のメソッド(AddData)を呼び出せば、
共有オブジェクトである RemotingCommon にデータが登録されます。
このサンプルでは、サーバー側でタイマーを使ってそれを読み取っていますね。


> サーバー/クライアント双方の操作が可能になりました。
.NET Remoting で双方向通信を行うその他のサンプルとして。
http://axion.sakura.ne.jp/TwoWayComm_dotNetRemoting.html
http://d.hatena.ne.jp/coma2n/20071117/1195281882
http://www.codeproject.com/KB/IP/TwoWayRemoting.aspx
2010/07/16(Fri) 10:36:18 編集(投稿者)

■No27090に返信(すのうさんの記事)
お世話になっております

moto-square様のサンプルをみるとサーバーオブジェクトは
static変数にデータを入れてやりとりしています。
サーバーオブジェクトのインスタンスが同一でなくても
クラス単位で共有するstatic変数でならやりとり出来る、ということですね。

多分、すのうさんがお聞きしたい事はコレだと思うのですが……。
見当違いでしたらすいません。
ご回答、ありがとうございます
全体的に説明不足だったようで申し訳ありません。

>Azulean様
自分でmsdnのサンプルを改造した際に
サーバー側のオブジェクトにもActivator.GetObjectで作成した
プロキシを使用しないとサーバー側からクライアントオブジェクトを
操作出来なかったのですが、moto-square様のサンプルでは
Activator.GetObjectでは無くコンストラクタで初期化しただけで
クライアントからのデータを取得出来ていたので何故かな?と思った次第です。

>魔界の仮面弁士様
はい、moto-square様のサンプルが双方向通信で無い事は理解しています。

実際にやったこととしましては(上記Azulean様へのレスと重なりますが)、
クライアント側で登録したサーバーオブジェクト
(インスタンスC/中身はプロキシ)のプロパティの一つとして
クライアントオブジェクトを持たせ、
サーバー側のサーバーオブジェクト
(インスタンスS/中身もサーバーオブジェクト)からプロパティに入っている
クライアントオブジェクトに対して操作を行う。
という処理でした。

インスタンスCの実態はプロキシですので
インスタンスSとの関わりが当然無ありません。
そこで、サーバー側のサーバーオブジェクトにも
Activator.GetObjectでプロキシを入れることで
サーバー側からクライアントオブジェクトを触る事に成功しました。

しかし、moto-square様のサンプルでは
クライアントから渡されたデータ
(=サーバーオブジェクトの変数に入れられたデータ)を
プロキシを介すること無く、取得出来ていたので
どういう方法なのか?と疑問に思った次第です。

それに対する回答は下記のぱいら様へのレスになるのですが……

>ぱいら様
ありがとうございます
staticの部分をすっかり見落としていたようです。これで謎が解けました。

お騒がせしたようで申し訳ありません。
お三方共、ご回答ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板