こんにちは、Habr!
作業の過程で、異なるネットワークインターフェイス(ローカルネットワークとインターネット)を介してアクセス可能な複数のRMIレジストリを作成するタスクが登場しました。 そして驚いたことに、私はこの問題に関してネットワーク上で何も見つけられませんでした。 そのため、自分で解決したので、このソリューションを人々と共有することにしました。
与えられた
ローカルIPアドレスと外部IPアドレスの2つのネットワークインターフェイスを備えたサーバー。 クライアントが使用し、サーバーが実装するインターフェース:
public interface Server extends Remote { public String getMessage() throws RemoteException; }
挑戦する
それぞれ独自のネットワークインターフェイス用に2つのRMIレジストリを作成します。
解決策
読者がRMIの基本に精通していることを理解していることをすぐに予約します(そうでない場合は、
こちら 、
こちら 、
こちらを
ご覧ください )。レジストリを作成するとき、java.rmi.server.hostnameパラメーターで指定されたアドレスに登録します。 したがって、各レジストリを作成する前にホスト名の値を設定します。 インターネットからアクセスするには、RMIがレジストリ用とオブジェクト用の2つのポートを使用することを覚えておくことが重要です。 つまり インターネットから2つのポートへのアクセスを開く必要があります。 オブジェクトの作成時にポートを指定しない場合、匿名ポートで作成されますが、インターネットからアクセスできない場合があります。 そのため、手順は次のとおりです。
- ポートとのインターフェイスの実装を記述します。
- ローカルネットワークのレジストリを作成します。
- オブジェクトを作成し、レジストリに登録します。
- 外部IPアドレスの値をjava.rmi.server.hostnameに渡します。
- 開いているポートの1つに外部ネットワークのレジストリを作成します。
- 2番目の開いているポートで外部ネットワークのオブジェクトを作成し、レジストリに登録します。
- 利益
インターフェイス実装
インターフェイスの実装では、ポートがコンストラクターで示される
ことが重要です。
public final class ServerImpl extends UnicastRemoteObject implements Server { public ServerImpl(int port) throws RemoteException { super(port); } @Override public String getMessage() throws RemoteException { return "hello"; } }
レジストリを作成する
Registry localRegistry = LocateRegistry.createRegistry(localPort);
2つのRMIレジストリを取得し、それぞれ独自のインターフェイスからアクセスできます。 追加のレジストリ分離のために、独自の
RMIClientSocketFactoryおよび
RMIServerSocketFactory実装を
記述して 、
指定されたアドレスのみをリッスンするようにソケットを構成することもできます。 しかし、私は独立した研究のためにそれを残します。