Java 确保RMI仅在一个服务器实例上运行
我目前正试图通过实现一个服务器/客户机结构来掌握RMI的基本知识,在这个结构中,客户机可以调用服务器上的远程操作,服务器可以调用客户机函数:Java 确保RMI仅在一个服务器实例上运行,java,rmi,Java,Rmi,我目前正试图通过实现一个服务器/客户机结构来掌握RMI的基本知识,在这个结构中,客户机可以调用服务器上的远程操作,服务器可以调用客户机函数: public class Client extends GenericRMI implements ClientInterface { public ServerInterface server; public Client() { try { String IP = InetAddress.getLocalHos
public class Client extends GenericRMI implements ClientInterface {
public ServerInterface server;
public Client() {
try {
String IP = InetAddress.getLocalHost().getHostAddress();
server = (ServerInterface) Naming.lookup("//192.168.2.124/WServer");
int uniqueID = (int) Math.round(Math.random() * 1000);
super.setUpRMI("WClient" + IP + "_" + uniqueID);
server.registerNewClient(IP, uniqueID);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setUserID(int id) {
System.out.println("got my ID from the server: " + id);
}
}
public class Server extends GenericRMI implements ServerInterface {
private List<ClientInterface> clients;
public Server() {
clients = new ArrayList<ClientInterface>();
super.setUpRMI("WServer");
}
public void registerNewClient(String IP, int uID) throws RemoteException {
try {
ClientInterface c = (ClientInterface) Naming.lookup("//" + IP + "/WClient" + IP + "_"
+ uID);
int newID = clients.size();
clients.add(c);
c.setUserID(newID);
} catch (Exception e) {
e.printStackTrace();
}
}
}
接口由
public interface ServerInterface extends Remote...
RMI设置
public class GenericRMI implements Remote, Serializable {
protected Registry registry;
public void setUpRMI(String bindName) {
if (registry == null) {
try {
registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
} catch (ExportException e) {
// client and server on one PC
} catch (RemoteException e) {
e.printStackTrace();
}
}
try {
Naming.rebind(bindName, this);
} catch (RemoteException | MalformedURLException e) {
e.printStackTrace();
}
System.out.println("Started " + bindName);
}
}
然而,输出就像
Started WServer
Started WClient192.168.2.124_501
got my ID from the server: 0
Started WClient192.168.2.124_655
got my ID from the server: 0
Started WClient192.168.2.124_771
got my ID from the server: 0
即使我调试它,服务器对每个客户机都有不同的ID。我想我在某个地方犯了一个可怕的错误,因为我曾经认为服务器只会运行一个实例。我怎样才能做到这一点
编辑
问题是,;如果调试registerNewClient()函数,则每个客户端的相应服务器对象都会更改: Server@7728992 Server@5fbb71ac ...
即使我让客户列表同步,也没用。但是,将clients字段设置为transient server-side会导致其出现空指针异常,这表明它确实是一个新实例。您只有一个实例在运行。您只调用了一次
new Server()
,而且在任何情况下都无法将三个实例绑定到注册表中的同一个名称。您更有可能在未同步的“客户端”集合上遇到并发问题。问题是;如果调试registerNewClient()函数,则每个客户端的相应服务器对象都会更改:Server@7728992 Server@5fbb71ac ... 即使我让客户列表同步,也没用。但是,在服务器端设置clients字段会导致其出现空指针异常,这表明它确实是一个新实例。您需要使genericmi扩展UnicastRemoteObject。在移动时,它根本不是一个远程对象。
Started WServer
Started WClient192.168.2.124_501
got my ID from the server: 0
Started WClient192.168.2.124_655
got my ID from the server: 0
Started WClient192.168.2.124_771
got my ID from the server: 0