0
我目前正試圖通過實現服務器/客戶端結構來獲取RMI的基礎知識,其中客戶端可以調用服務器上的遠程操作,並且服務器可以調用客戶端功能:確保RMI只在一個服務器實例上運行
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();
}
}
}
和,在主函數:
new Server();
Thread.sleep(1000);
new Client();
Thread.sleep(1000);
new Client();
Thread.sleep(1000);
new Client();
接口由
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()函數,各自的服務器對象更改爲每個客戶端: 服務器@ 7728992 服務器@ 5fbb71ac ... 即使我讓客戶端列表同步,它並沒有幫助。但是,使客戶端字段暫時服務器端導致它的空指針異常,表明它確實是一個新的實例。
問題是;如果我調試registerNewClient()函數,各自的服務器對象更改爲每個客戶端: 服務器@ 7728992 服務器@ 5fbb71ac ... 即使我讓客戶端列表同步,它並沒有幫助。但是,使客戶端字段暫時服務器端導致它的空指針異常,表明它確實是一個新的實例。 – Zahlii
您需要使GenericRMI擴展UnicastRemoteObject。在運動中,它根本不是一個遠程對象。 – EJP
謝謝,我發現了這一點,當我注意到你的迴應! – Zahlii