Hallo Leute,
ich hoffe ihr könnt mir helfen. Ich verzweifel schon ein wenig.
Und zwar wollte ich mich ein bisschen in RMI einarbeiten und hab gedacht ich fang klein an um zu schauen wie das alles genau funktioniert und programmiere ein ganz simples Chat-Programm. Tja, nur funktioniert das leider nicht so, wie ich will. Ich poste erstmal den Code und schreibe dann, was nicht funktioniert. Beachtet erstmal die Kommentare nicht, die brauche ich später für weitere Erklärungen.
Das Server-Interface IServer:
Die implementierende Server-Klasse Server:
Ein Listener-Interface IListener:
Und die implementierende Klasse Listener:
Und zu guter letzt die Client-Klasse Client:
So, wenn ich jetzt alles starte - keine Fehlermeldung kommt - und ich nun etwas ins Textfeld eingebe und senden drücke, passiert gar nichts. Wieso?
Interessant ist, dass wenn ich das, was als "Teil 1" kommentiert ist an "Platz 1" packe, also im Prinzip hinter das addClient, dann kommt nach dem senden eine NullPointerException in der Methode print. Also so, dass ta ein NullPointer ist. Wieso das denn?
Aber die print-Methode selbst funktioniert. Wenn ich in die print-Methode anstatt "ta.append(...)" nämlich "System.out.println(...)" hineinschreibe, wird es in der Konsole ausgegeben. Es muss also irgendetwas mit der JTextArea zu tun haben, aber ich verstehe nicht was. Vielleicht habe ich die Funktionsweise von RMI nicht richtig verstanden oder so.
Ich wäre für jede Hilfe/Erklärung wirklich dankbar!!
Falls etwas nicht verstanden wurde, weil ich es nicht vernünftig beschrieben habe, bitte einfach nachfragen!
ich hoffe ihr könnt mir helfen. Ich verzweifel schon ein wenig.
Und zwar wollte ich mich ein bisschen in RMI einarbeiten und hab gedacht ich fang klein an um zu schauen wie das alles genau funktioniert und programmiere ein ganz simples Chat-Programm. Tja, nur funktioniert das leider nicht so, wie ich will. Ich poste erstmal den Code und schreibe dann, was nicht funktioniert. Beachtet erstmal die Kommentare nicht, die brauche ich später für weitere Erklärungen.
Das Server-Interface IServer:
Code:
public interface IServer extends Remote {
public void addClient(IListener l) throws RemoteException;
public void removeClient(IListener l) throws RemoteException;
public void sendMessage(String s) throws RemoteException;
}
Die implementierende Server-Klasse Server:
Code:
public class Server implements IServer {
private ArrayList<IListener> clients;
public Server() {
try {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
IServer server = (IServer) UnicastRemoteObject.exportObject(this, 0);
Registry reg = LocateRegistry.getRegistry();
reg.bind("Chat", server);
clients = new ArrayList<IListener>();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AlreadyBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void addClient(IListener l) throws RemoteException {
clients.add(l);
}
@Override
public void removeClient(IListener l) throws RemoteException {
clients.remove(l);
}
@Override
public void sendMessage(String s) throws RemoteException {
for (IListener l : clients) {
l.receiveMessage(s);
}
}
public static void main(String[] args) {
new Server();
}
}
Ein Listener-Interface IListener:
Code:
public interface IListener extends Remote, Serializable {
public void receiveMessage(String s) throws RemoteException;
}
Und die implementierende Klasse Listener:
Code:
public class Listener implements IListener {
Client client;
public Listener(Client client) {
this.client = client;
Registry reg;
try {
reg = LocateRegistry.getRegistry();
reg.bind("Listener_" + client.getName(), this);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AlreadyBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void receiveMessage(String s) throws RemoteException {
client.print(s);
}
}
Und zu guter letzt die Client-Klasse Client:
Code:
public class Client extends JFrame {
private String name;
IServer server;
IListener listener;
JTextArea ta;
public Client() {
super("Chat");
name = JOptionPane.showInputDialog("Bitte Name eingeben: ");
//----------------Teil 1
this.setVisible(true);
this.setSize(500, 500);
this.setLocationRelativeTo(null);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
server.removeClient(listener);
} catch (RemoteException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.exit(0);
}
});
addComps();
//Teil 1-----------------------------
listener = new Listener(this);
Registry reg;
try {
reg = LocateRegistry.getRegistry();
server = (IServer) reg.lookup("Chat");
server.addClient(listener);
} catch (RemoteException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Platz 1
}
private void addComps() {
ta = new JTextArea();
ta.setLineWrap(true);
ta.setWrapStyleWord(true);
ta.setEditable(false);
JPanel inputPanel = new JPanel(new FlowLayout());
final JTextField tf = new JTextField(25);
JButton send = new JButton("Send");
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
server.sendMessage(name + ": " + tf.getText());
} catch (RemoteException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
inputPanel.add(tf);
inputPanel.add(send);
this.getContentPane().add(ta, BorderLayout.CENTER);
this.getContentPane().add(inputPanel, BorderLayout.SOUTH);
}
public void print(String s) {
ta.append(s + "\n");
}
public static void main(String[] args) {
new Client();
}
}
So, wenn ich jetzt alles starte - keine Fehlermeldung kommt - und ich nun etwas ins Textfeld eingebe und senden drücke, passiert gar nichts. Wieso?
Interessant ist, dass wenn ich das, was als "Teil 1" kommentiert ist an "Platz 1" packe, also im Prinzip hinter das addClient, dann kommt nach dem senden eine NullPointerException in der Methode print. Also so, dass ta ein NullPointer ist. Wieso das denn?
Aber die print-Methode selbst funktioniert. Wenn ich in die print-Methode anstatt "ta.append(...)" nämlich "System.out.println(...)" hineinschreibe, wird es in der Konsole ausgegeben. Es muss also irgendetwas mit der JTextArea zu tun haben, aber ich verstehe nicht was. Vielleicht habe ich die Funktionsweise von RMI nicht richtig verstanden oder so.
Ich wäre für jede Hilfe/Erklärung wirklich dankbar!!

Falls etwas nicht verstanden wurde, weil ich es nicht vernünftig beschrieben habe, bitte einfach nachfragen!