RMI(リモートメソッド呼び出し)

そのため、提起されたタスクではリモートメソッド呼び出しを使用する必要がありました。 Habréについて調べたところ、この問題については何も見つかりませんでした(ドキュメントを読む前に、最初の知り合いとして何かを読みたかったのです)。 java.sun.comで仕様を検討したので、私はあなたと私の最初の記事を急いで共有します。 :)



「RMIとは」



リモートメソッド呼び出し-リモートオブジェクトのメソッドを呼び出すことができるメカニズム。 彼によると、データを準備および送信するためのすべての操作は、クライアントスタブオブジェクト(スタブ)の呼び出されたメソッドにカプセル化されます。 メソッド呼び出し自体は、いくつかの例外を除き、通常のローカルオブジェクトのメソッド呼び出しと同じです。

また、メソッドを呼び出すときは、リモートクラスではなくリモートインターフェイスで作業していることに注意してください。



「なぜこれが必要なのですか?」



RMIのタスクは、クライアントとサーバーの相互作用の編成です。 つまり、データ転送や前処理(プロトコルなど)を心配する必要はありません。 便利ですか? はい しかし、すべての場合ではありません。 クライアント/サーバー環境がjavaで書かれたプログラムの作業を暗示している場合、RMIはほとんど役に立ちません(ただし、JNIを使​​用して「抜け出す」ことができます)。



「何かを書きましょう!」



さあ 分散コンピューティングの例を考えてみましょう。 私たちの仕事はこれです:列挙によって最も簡単な方法で素数を検索します。 分散方式で、2からsqrt(n)の除数を選択して数値を確認します。nは確認する数値です。 (「分散コンピューティング」はそのような例の大きな名前です。しかし、私たちは計算していますか?はい!分散していますか?分散しています!)



この方法で問題を解決します:「登録済み」クライアントに検証用の番号を「フィード」するサーバーがあるため、双方向でやり取りします(クライアント->サーバー-登録、サーバー->クライアント-検証用の番号)、これについて説明します2インターフェース:

public interface ClientRegister extends Remote { public void register (PrimeChecker checker) throws RemoteException; } public interface PrimeChecker extends Remote { public boolean check (BigDecimal number) throws RemoteException; } * This source code was highlighted with Source Code Highlighter .



  1. public interface ClientRegister extends Remote { public void register (PrimeChecker checker) throws RemoteException; } public interface PrimeChecker extends Remote { public boolean check (BigDecimal number) throws RemoteException; } * This source code was highlighted with Source Code Highlighter .



  2. public interface ClientRegister extends Remote { public void register (PrimeChecker checker) throws RemoteException; } public interface PrimeChecker extends Remote { public boolean check (BigDecimal number) throws RemoteException; } * This source code was highlighted with Source Code Highlighter .



  3. public interface ClientRegister extends Remote { public void register (PrimeChecker checker) throws RemoteException; } public interface PrimeChecker extends Remote { public boolean check (BigDecimal number) throws RemoteException; } * This source code was highlighted with Source Code Highlighter .



  4. public interface ClientRegister extends Remote { public void register (PrimeChecker checker) throws RemoteException; } public interface PrimeChecker extends Remote { public boolean check (BigDecimal number) throws RemoteException; } * This source code was highlighted with Source Code Highlighter .



  5. public interface ClientRegister extends Remote { public void register (PrimeChecker checker) throws RemoteException; } public interface PrimeChecker extends Remote { public boolean check (BigDecimal number) throws RemoteException; } * This source code was highlighted with Source Code Highlighter .



  6. public interface ClientRegister extends Remote { public void register (PrimeChecker checker) throws RemoteException; } public interface PrimeChecker extends Remote { public boolean check (BigDecimal number) throws RemoteException; } * This source code was highlighted with Source Code Highlighter .



public interface ClientRegister extends Remote { public void register (PrimeChecker checker) throws RemoteException; } public interface PrimeChecker extends Remote { public boolean check (BigDecimal number) throws RemoteException; } * This source code was highlighted with Source Code Highlighter .





ClientRegisterインターフェースは、クライアントが自身をPrimeChecker`aとしてサーバーに登録するために使用します。 サーバーはPrimeCheckerを使用して、確認のためにクライアントに番号を送信します。



既にお気付きのように、リモートインターフェイスは、リモートインターフェイスを直接または間接的に拡張する必要があります。 他の例外の中でも、RemoteExceptionを定義します(上記で説明しました)。



サーバーの実装を開始しましょう( 完全なコード ):





  1. パブリック クラス PrimeNumbersSearchServerはClientRegisterを実装します{
  2. ...
  3. public static void main( String [] args){
  4. PrimeNumbersSearchServerサーバー= 新しい PrimeNumbersSearchServer();
  5. {
  6. ClientRegisterスタブ=(ClientRegister)UnicastRemoteObject.exportObject(server、0);
  7. レジストリregistry = LocateRegistry.createRegistry(12345);
  8. registry.bind( "ClientRegister" 、スタブ);
  9. server.startSearch();
  10. } catch (例外e){
  11. システム out .println( "エラーが発生しました:" + e.getMessage());
  12. System.exit(1);
  13. }
  14. }
  15. }
*このソースコードは、 ソースコードハイライターで強調表示されました。


初期化を分析しましょう:





  1. ClientRegisterスタブ=(ClientRegister)UnicastRemoteObject.exportObject(server、0);
*このソースコードは、 ソースコードハイライターで強調表示されました。


リモートオブジェクトをエクスポートし、スタブを取得します。スタブを介して、クライアントはオブジェクトのメソッドを呼び出します。 2番目のパラメーターexportObjectは、リモートオブジェクトへの接続に使用されるポートであり、0は任意の空きポートの選択です。 スタブをクライアントに渡す必要があります。 ここでは、まったく異なるオプションが可能です。 3.5 ''フロッピーディスクでクライアントにスタブを渡すこともできます:) RMIレコーダーを使用します。 vm内で作成するか、rmiregistryユーティリティで表される「外部」を使用できます。 最初のオプションを使用しました:





  1. レジストリregistry = LocateRegistry.createRegistry(12345);
  2. registry.bind( "ClientRegister" 、スタブ);
*このソースコードは、 ソースコードハイライターで強調表示されました。


レジストラを作成し、ClientRegisterという名前でスタブをバインドします。 レジストラは、ポート12345での接続を受け入れます。



クライアント( 完全なコード ):





  1. パブリック クラス PrimeNumbersSearchClientはPrimeCheckerを実装します{
  2. ...
  3. public static void main( String [] args){
  4. PrimeNumbersSearchClient client = new PrimeNumbersSearchClient();
  5. {
  6. レジストリregistry = LocateRegistry.getRegistry( null 、12345);
  7. ClientRegisterサーバー=(ClientRegister)registry.lookup( "ClientRegister" );
  8. PrimeCheckerスタブ=(PrimeChecker)UnicastRemoteObject.exportObject(client、0);
  9. server.register(スタブ);
  10. } catch (例外e){
  11. システム out .println( "エラーが発生しました:" + e.getMessage());
  12. System.exit(1);
  13. }
  14. }
  15. }
*このソースコードは、 ソースコードハイライターで強調表示されました。


クライアントは、登録するためにサーバースタブを取得する必要があります。





  1. レジストリregistry = LocateRegistry.getRegistry( null 、12345);
  2. ClientRegisterサーバー=(ClientRegister)registry.lookup( "ClientRegister" );
*このソースコードは、 ソースコードハイライターで強調表示されました。


リモートレジストラを見つけて、それに関連付けられた「ClientRegister」という名前のスタブを要求します。 最初のパラメーターはLocateRegistry.getRegistry(null、12345)がホスト(nullはlocalhost)で、2番目はポートです。



次に、クライアントリモートオブジェクトをエクスポートし、それをスタブサーバー(既にクライアント)に渡します-登録します。 サーバーは、利用可能なチェッカーのキューにクライアントを追加し、確認のために彼に番号の送信を開始します。 チェックした後、エラーなしで完了した場合、クライアントは再びキューに入ります。



UPD:Javaに移植



All Articles