simple RMI chat problem

A

Angus Parvis

Hi,

I want to implement a simple RMI chat with a (Swing-)GUI on the client
side. I manage to send a chat-message to the server and from there to
all clients.
But here the strange things start: the output that should appear in the
client's window appears in the server's. And the client is unable to
access the textarea ment to display the incoming chat messages.

I'm working with Java 1.5 under WinXP Pro. These are commands i use to
start the app:

rmic chat.server.ChatServer
start rmiregistry
start java -Djava.security.policy=policy.txt chat.server.ChatServer
start java -Djava.security.policy=policy.txt chat.client.ChatClient

The source code and the policy file are attached to this posting.

Maybe someone can point me to an existing solution or give a hint
himself. Thx for any help.

Cheers,
Angus

package chat.client;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import chat.server.IChatServer;

public class ChatClient extends JFrame implements ActionListener {

private JTextArea _textarea = new JTextArea();

private JTextField _inputField = new JTextField();

private IChatServer _chatServer;

private void createGUI() {
setSize(400, 600);

Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
_textarea.setEditable(true);
contentPane.add(new JScrollPane(_textarea), BorderLayout.CENTER);

JPanel inputPanel = new JPanel(new BorderLayout());
inputPanel.add(_inputField, BorderLayout.CENTER);
JButton sendButton = new JButton("Send");
sendButton.addActionListener(this);
inputPanel.add(sendButton, BorderLayout.LINE_END);
contentPane.add(inputPanel, BorderLayout.PAGE_END);
}

public ChatClient(IChatServer chatServer) throws RemoteException {
super("Chat Client");
_chatServer = chatServer;
_chatServer.addClient(this);

createGUI();
}

public void actionPerformed(ActionEvent event) {
try {
_chatServer.sendMessage(_inputField.getText());
} catch (RemoteException e) {
e.printStackTrace();
}
}

public void receiveMessage(String message) {
System.out.println("client: message received: " + message);
_textarea.setText(_textarea.getText() + "\n" + message);
}

public static void main(String args[]) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
ChatClient client = new ChatClient((IChatServer) Naming
.lookup("Chat"));
client.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package chat.server;

import java.rmi.Remote;
import java.rmi.RemoteException;

import chat.client.ChatClient;

public interface IChatServer extends Remote {
public void sendMessage(String message) throws RemoteException;

public void addClient(ChatClient client) throws RemoteException;
}
package chat.server;

import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Iterator;

import chat.client.ChatClient;

public class ChatServer extends UnicastRemoteObject implements IChatServer {
private ArrayList<ChatClient> _clients = new ArrayList<ChatClient>();

public ChatServer() throws RemoteException {
}

public synchronized void sendMessage(String message) throws RemoteException {
System.out.println("server: received message: " + message);
for (ChatClient client : _clients) {
System.out.println("Sending to client.");
client.receiveMessage(message);
}
}

public void addClient(ChatClient client) throws RemoteException {
_clients.add(client);
System.out.println("server: client registered");
}

public static void main(String[] args) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
String name = "Chat";
System.out.println("Starting service " + name);
try {
IChatServer server = new ChatServer();
Naming.rebind(name, server);
System.out.println("ChatServer bound");
} catch (Exception e) {
System.err.println("ChatServer exception: " + e.getMessage());
e.printStackTrace();
}
}
}
grant {
permission java.security.AllPermission;
};
 
B

BartCr

Using RMI to implement a chat service is not simple, and certainly not
the best way to implement it.

The chat server is registering itself correctly. The client register
themselves with the chat server, this means, the chat client objects
created are sent to the server and stored in an arraylist there. These
chat client objects are not remote or anything, so there is no way for
the server to get back to the clients.

A way to solve this is to create an interface IChatClient extends
Remote and register (rebind) a unique service name to the rmi registery
for each chat client. Register this name also in the chat server and
use Naming.lookup to collect the chat clients. (two way rmi)

A simpler solution is to use plain socket communication between server
and clients (keep open sockets) and build a protocol on top of this
socket. (could be quite simple to start: sending of plain strings). IRC
is build on an implementation of this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top