pl ja de zh ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ru en en ja ja ja ja ja ja ja de ja de ja de ja de ja de en en en ja de ja de ja en ja en en ja de ja de ja de ja de ja de ja de ja en ja ja de ja th ja sv ja de ja de ja de ja de ja de ja
dRuby は Ruby 専用の分散オブジェクトシステムです。 Ruby のみで記述され、TCP socket のような Ruby 本体が提供する通信手段があれば追加のインストール物なしに利用可能です。独自のプロトコルで通信し、他の分散オブジェクトシステム (CORBA, RMI, .NETなど)との相互運用性はありません。
リモートプロセスにあるオブジェクトはローカルには DRb::DRbObject のインスタンスとして表現されます。このオブジェクトはリモートオブジェクトの proxy のように振舞います。つまり、このオブジェクトのメソッドを呼び出すとリモートオブジェクトに転送されます。 CORBA の IDL のようなリモートオブジェクトのインターフェースを静的に宣言する必要はなく、すべては実行時に解決されます。
リモートプロセスからのメソッド呼出しはそれを受け取ったプロセスの DRb::DRbServer オブジェクトが処理します。受け取ったメッセージからメソッド呼出し情報を取り出し、ローカルにあるオブジェクトを特定し、そのメソッドを呼び出し、返り値をリモートの呼び出し元に送ります。どのようなオブジェクトのメソッドも呼びだすことができます。何か特別なインターフェースを実装したり、特別な mixin を必要としたりはしません。オブジェクトの特定は DRb::DRbServer が自動でします。そのためオブジェクトの登録のようなことは通常必要ありません。
ただし、マーシャリング不可能なオブジェクトは dRuby によってある種のリファレンスとして取り扱われます。これは DRb::DRbObject のインスタンスとして表現されます。これはリモートオブジェクトの proxy として動作し、proxy のメソッドを呼び出すと上に説明した通りの方法でリモートオブジェクトのメソッドを呼び出します。
マーシャリング可能なオブジェクトを DRbObject でリファレンスとして渡したい、つまりコピーでなくリファレンスで渡したい場合はそのオブジェクトに DRb::DRbUndumped を Module#include します。
dRuby はブロック付きのメソッド呼び出しをサポートしていますが、 Proc はマーシャリング不可能なので、ブロックの中身は (リモート側でなく)ローカルプロセス上で実行されます。リモート側がブロックを呼び出そうとすると、ブロックの引数がリモート側からローカル側に(上で説明したようにコピーもしくは dRuby のリファレンスオブジェクトとして)渡され、ブロックが実行され、その返り値がリモート側に送られます。
dRuby でインターネット上に公開するサービスを作るべきではありません。イントラネットのサービスとして動かす場合もセキュリティには気を使う必要があるでしょう。
あるオブジェクトへの外部からのアクセスを許可すると、単にそのオブジェクトのメソッドを外部から呼び出せるだけでなく、任意の Ruby のコードを実行できてしまいます。例えば以下のようなことができます。
# !! 危険 !! ro = DRbObject.new_with_uri("druby://your.server.com:8989") class << ro # リモートオブジェクトの instance_eval を呼ぶため # ローカルオブジェクトの instance_eval を取り除く undef :instance_eval end ro.instance_eval("DANGEROUS RUBY CODE!")
このような instance_eval による危険性は $SAFE を 1 にすることで防げます。 DRb.#start_service の :safe_level オプションでリモートからのメソッド呼び出しのコンテキストで指定されるセーフレベルを指定できます。
また、DRb::DRbServer にはアクセスコントロールリスト(アクセスを許可/拒否する IP のリスト)によりアクセス制御をすることができます。この機能は ACL で実現されています。このアクセス制御は単体で使うのではなく、適切なファイアウォールと併用すべきです。
http://www2a.biglobe.ne.jp/~seki/ruby/druby.html
http://www.ruby-doc.org/stdlib/libdoc/drb/rdoc/index.html
単純なクライアント-サーバシステムの例。
ターミナルを2つサーバ側/クライアント側として起動して、サーバ側を先に動かしてください。
require 'drb/drb' # 通信を待ち受ける URI SERVER_URI="druby://localhost:8787" class TimeServer def get_current_time return Time.now end end # サーバ側でリクエストを受け付けるオブジェクト FRONT_OBJECT=TimeServer.new # サーバを起動する DRb.start_service(SERVER_URI, FRONT_OBJECT, :safe_level => 1) # DRb のスレッドが終了するのを待つ DRb.thread.join
require 'drb/drb' # 接続先の URI SERVER_URI="druby://localhost:8787" # DRbサーバを起動する # この例には必要ないが、front オブジェクト以外の # リモートオブジェクトのメソッドを呼び出す時には必要 DRb.start_service # リモートオブジェクトの取得 timeserver = DRbObject.new_with_uri(SERVER_URI) # リモートメソッドの呼び出し puts timeserver.get_current_time
DRb::DRbIdConv
オブジェクトと識別子を相互に変換するクラスです。
DRb::DRbObject
リモートの dRuby オブジェクトを表すオブジェクトです。
DRb::DRbServer
dRuby サーバクラス。
DRb::DRbUnknown
リモートプロセスからマーシャリングされて送られてきたオブジェクトで、そのクラスがローカルプロセス内では不明であるようなものを表すクラス。
Alias of DRb::DRbIdConv
Alias of DRb::DRbObject
drb ライブラリの名前空間となるモジュール。
DRb::DRbProtocol
drb で使われる通信プロトコルを取り扱うモジュールです。
DRb::DRbUndumped
このモジュールをインクルードしたクラスのインスタンスはネットワーク越しに参照渡しで渡されるようになります。値渡し出来ないオブジェクトを drb と一緒に使う時に有用です。
DRbUndumped
Alias of DRb::DRbUndumped
DRb::DRbError
drb ライブラリ固有の例外を表すクラス
DRb::DRbBadScheme
プロトコルクラスが受け取った URI の schema がそのクラスでサポートされていないことを、伝えるための例外。
DRb::DRbBadURI
URI に含まれている schema をサポートしているプロトコルが見付からないことを意味する例外クラス。
DRb::DRbConnError
通信エラーが発生したことを意味する例外クラス。
DRb::DRbRemoteError
例外オブジェクトを wrap したクラス
DRb::DRbServerNotFound
カレントサーバが見付からない場合に発生する例外のクラス
DRb::DRbUnknownError
DRb::DRbUnknown をラップする例外クラスです。
drb で用いる ACL(Access Control List)を定義するライブラリ。
drb/extserv
DRb::ExtServ を定義しているライブラリ。
drb/extservm
DRb::ExtServManager を定義しているライブラリ。
drb 通信を中継するゲートウェイ(DRb::GW)と、中継に必要なオブジェクト識別子変換クラス(DRb::GWIdConv)、および DRb::DRbObject への拡張が含まれています。
drb/observer
DRb 用の修正をした Observable (DRb::DRbObservable) を定義するライブラリ。
DRb のプロトコルとして SSL/TLS 上で通信する drbssl が使えるようになります。
drb/timeridconv
DRb::DRbIdConv の拡張 DRb::TimerIdConv を定義するライブラリ。 DRb::DRbIdConv の GC 問題をタイムアウトを定めることで部分的に解決します。
DRb のプロトコルとして UNIX ドメインソケット経由で通信する drbunix が使えるようになります。