すべてのネットワーク通信に RMI を使用して Java でゲームを開発しています。RMI を使用すると、サーバーでメソッドを呼び出すことができますが、それだけでは十分ではありません。また、サーバーが接続されたクライアント間でメッセージを拡散できるようにしたいと考えています。
私のクライアントはサーバーを検索し(インターフェースはリモートを拡張します)、登録します。これにより、サーバーは誰が接続しているかを知ることができます。私のクライアントは、Remote を拡張するインターフェースも実装しています。ここに私のコードの一部があります:
インターフェイス宣言:
public interface IServer extends Remote {
void connect(IClient Client) throws RemoteException, ExistingItemException;
//...
}
public interface IClient extends Remote {
public void notify(Notification Notification) throws RemoteException;
//...
}
サーバ側:
//int RMIPort = 1099, ServerPort = 1100;
IServer Server = new RMIServer();
IServer Proxy = (IServer) UnicastRemoteObject.exportObject(Server, ServerPort);
LocateRegistry.createRegistry(RMIPort).rebind("//" + LocalIP + ":" +
RMIPort + "/xxx", Proxy);
クライアント側:
//Sets the local reference to IServer and creates the IClient
setInstance(new Client(Login, (IServer) LocateRegistry.getRegistry(RemoteIP).
lookup("//" + RemoteIP + ":" + RMIPort + "/xxx")));
//Gets the IClient and makes it available for the IServer to call notify(...)
Proxy.connect((IClient) (UnicastRemoteObject.exportObject(getInstance(), 0)));
このソリューションはローカルでは機能しますが、インターネット経由で使用しようとすると機能しません。
コンピューターを固定 IP アドレスに公開し、1099 および 1100 ポートを転送するようにルーターをセットアップしました。このソリューションでは、他の開発者が私のサーバーを「検索」して、有効で使用可能なプロキシを取得できますが、IClient をエクスポートすることはできません。JVM がオブジェクトをローカル ネットワークにエクスポートしようとしているようで、実行はここで停止します。
-Djava.rmi.server.hostname=my-external-IP
そのため、サーバーのローカルとクライアントのリモートの両方で JVM 引数を渡そうとしました。そうすることで、exportObjectConnectException
はローカル ip ではなくリモート ip に a をスローします。