多くのクライアントが接続するRMIサーバーがあります。クライアントが変更を登録すると、サーバーが反応し、すべてのクライアントに変更を行うように指示します。
私はいくつかのhelloworldRMIの例を調べてきましたが、サーバーからクライアントへの接続を維持する方法を扱っているものはありません。
私が達成したいのは、これらの線に沿ったものです。サーバーはrmiregistryに登録されています。クライアント1はサーバーに接続し、サーバー上のメソッドを呼び出します。クライアント2はサーバーに接続し、サーバー上のメソッドを呼び出します。サーバーは変更をclient2からclient1に送信します。
すべてのクライアントをサーバーとして登録せずに、これをどのように達成しますか?
編集:いくつかの優れた回答(よりフラットでよりフラット)を見た後、次の例外に遭遇していますjava.rmi.StubNotFoundException:スタブクラスが見つかりません:thegame.connectivity.GameClient_Stub; ネストされた例外は次のとおりです。
java.lang.ClassNotFoundException: thegame.connectivity.GameClient_Stub
at sun.rmi.server.Util.createStub(Util.java:292)
at sun.rmi.server.Util.createProxy(Util.java:140)
at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:196)
at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:310)
at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:237)
at thegame.connectivity.GameClient.bind(GameClient.java:37)
at thegame.connectivity.GameClient.run(GameClient.java:51)
at thegame.connectivity.GameClient.main(GameClient.java:29)
Caused by: java.lang.ClassNotFoundException: thegame.connectivity.GameClient_Stub
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at sun.rmi.server.Util.createStub(Util.java:286)
... 7 more
このクラスで
public class GameClient extends Thread implements Remote, Client, ModelChangeListener<Client>{
private static final long serialVersionUID = -394039736555035873L;
protected Queue<GameModelEvent> queue = new ConcurrentLinkedQueue<GameModelEvent>();
public GameClient(){
}
public static void main(String[] args){
GameClient client = new GameClient();
client.run();
}
protected void bind(){
System.setProperty("java.rmi.server.codebase","file:bin/");
try {
Registry registry = LocateRegistry.getRegistry();
Client c = (Client)UnicastRemoteObject.exportObject(this);
Server stub = (Server) registry.lookup("Server");
stub.registerClient(c);
} catch (RemoteException | NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
super.run();
bind();
while(!Thread.interrupted()){
System.out.print(".");
GameModelEvent event = queue.poll();
while(event != null){
System.out.println(event);
event = queue.poll();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
}
}
...
UnicatRemoteObjectをコメントアウトし、パラメーターとしてnullを渡すとうまく機能します。したがって、接続があり、すべてが実行されています。しかし、スタブはありません...コードベースをコメントアウトしても効果はありません。コードベースはサーバー上で正常に機能します。
何が悪いのかについて何か考えはありますか?