我的目標是製作一個簡單的聊天程序。我是RMI的新手。到目前爲止,我所得到的是服務器的工作原理。我開始吧。然後我啓動客戶端,它通過RMI將字符串傳輸到服務器。但是,它並沒有出現在我所做的GUI上。這就是我的問題所在。在使用RMI時GUI上不顯示文字
我StartClient類。我創建了一個chatClient,並將chatServer存根作爲參數。
public StartClient() throws RemoteException, NotBoundException, MalformedURLException {
chatServer = (ChatServer) Naming.lookup("rmi://localhost:1099/chatServer");
}
private void run() throws RemoteException, MalformedURLException, NotBoundException {
ChatClientImpl chatClient1 = new ChatClientImpl(chatServer, "ikke");
new ChatFrame(chatClient1);
ChatClientImpl chatClient2 = new ChatClientImpl(chatServer, "bla");
new ChatFrame(chatClient2);
}
public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException {
StartClient start = new StartClient();
start.run();
}
在ChatClientImpl構造我使用遠程方法寄存器。
public ChatClientImpl(ChatServer chatServer, String name) throws MalformedURLException, NotBoundException, RemoteException {
this.chatServer = chatServer;
this.name = name;
chatServer.register(this);
}
現在我們在ChatServerImpl類的REGISTER方法中。我將客戶端添加到客戶端的ArrayList。然後我使用SENT方法顯示文本。它調用每個客戶端對象都有的RECEIVE方法。
public class ChatServerImpl extends UnicastRemoteObject implements ChatServer {
private List<ChatClient> clients;
public ChatServerImpl() throws RemoteException {
this.clients = new ArrayList<ChatClient>();
}
public void register(ChatClientImpl client) throws RemoteException {
clients.add(client);
send("server", client.getName() + " has entered the room");
}
public void unregister(ChatClientImpl client) throws RemoteException {
clients.remove(client);
send("server", client.getName() + " has left the room");
}
public void send(String name, String message) throws RemoteException {
for(ChatClient client : clients) {
client.receive(name + ": " + message);
}
}
}
這是出問題的地方。 textReceiver始終爲空。 (textReceiver是屬性的客戶對象/場)。
public void receive(String message) {
if (textReceiver == null) return;
textReceiver.receive(message);
}
客戶的ArrayList的是服務器端和所有客戶端在那裏都對空集的textReceivers。如果你回頭看看StartClient,有一條重要的路線。新的ChatFrame(聊天客戶端)。在ChatFrame的構造函數中,我設置了textReceiver。
public ChatFrame(ChatClientImpl chatClient) {
this.chatClient = chatClient;
chatClient.setTextReceiver(this);
String name = chatClient.getName();
setTitle("Chat: " + name);
createComponents(name);
layoutComponents();
addListeners();
setSize(300, 300);
setVisible(true);
}
該項目工程時,我不使用RMI,他們是在一個封裝內,但一旦我把它們分爲客戶端服務器這種問題的出現。我如何在他們之間進行溝通?服務器端我有一個(無關緊要的)ChatClient列表,即使文本到達也不會影響任何內容。
我是否對每個單獨的ChatClient使用RMI並使ChatServer連接併發送文本?對我來說似乎很複雜。我如何去做這件事?
編輯:
ChatClientImpl類
public class ChatClientImpl implements ChatClient, Serializable {
private ChatServer chatServer;
private TextReceiver textReceiver;
private String name;
public ChatClientImpl(ChatServer chatServer, String name) throws MalformedURLException, NotBoundException, RemoteException {
this.chatServer = chatServer;
this.name = name;
chatServer.register(this);
}
public String getName() {
return name;
}
public void send(String message) throws RemoteException {
chatServer.send(name, message);
}
public void receive(String message) {
if (textReceiver == null) return;
textReceiver.receive(message);
}
public void setTextReceiver(TextReceiver textReceiver) {
this.textReceiver = textReceiver;
}
public void unregister() throws RemoteException {
chatServer.unregister(this);
}
}
ChatClientImpl是一個導出的遠程對象嗎?這發生在哪裏? 'setTextReceiver()'看起來像什麼? – EJP
setTextReceiver()是一個標準的setter。我在原始文章中編輯了ChatClientImpl類。使用「導出的遠程對象」,是否該類擴展了UnicastRemoteObject?不,我試過這樣做,但它爲chatServer.register(this)提供了IllegalArgumentException。 – Phosphophyllite