제 목표는 간단한 채팅 프로그램을 만드는 것입니다. 나는 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();
}
원격 메서드 레지스터를 사용합니다.
public ChatClientImpl(ChatServer chatServer, String name) throws MalformedURLException, NotBoundException, RemoteException {
this.chatServer = chatServer;
this.name = name;
chatServer.register(this);
}
이제 우리는 REGISTER 메서드의 ChatServerImpl 클래스에 있습니다. 클라이언트의 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는 항상 null입니다. (textReceiver이 속성은 클라이언트 객체의/필드입니다.)
public void receive(String message) {
if (textReceiver == null) return;
textReceiver.receive(message);
}
고객의 ArrayList를 자신의 textReceivers가 null에 설정되어이 모두 서버 측과 모든 클라이언트이다. StartClient를 돌아 보면 중요한 라인이 있습니다. 새 ChatFrame (chatClient)입니다. ChatFrame의 생성자에서 textReceiver를 설정합니다. 내가 RMI를 사용하지 않는 경우
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);
}
이 프로젝트
작동하고 하나 개의 패키지에있어하지만 난 클라이언트 - 서버로 분리하면이 문제가 발생했다. 어떻게 그들 사이에서 의사 소통을합니까? 서버 측 텍스트가 도착하더라도 영향을주지 않는 ChatClients 목록이 있습니다.별도의 모든 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()는 표준 설정 도구입니다. 내 원래 게시물에서 ChatClientImpl 클래스를 편집했습니다. "내 보낸 원격 객체"를 사용하면 클래스가 UnicastRemoteObject를 확장했는지 여부를 알 수 있습니까? 아니, 그 일을하려고했지만 chatServer.register (this)에 대한 IllegalArgumentException을 제공합니다. – Phosphophyllite