Question

As part of my lab this week I am suppose to convert a socket based chat application to RMI. So far I managed to connect server and client together and transfer data between them but the transfer is not continuous. What I mean is that when the client first connects t the server it broadcasts a message "X has entered the conversation" but that is all. Anything I type after that wont get broadcasted. I am about to pull out my hair. Please help.

public class ChatServer extends UnicastRemoteObject implements ChatMessage {

private static final long serialVersionUID = 1L;
private String sender;
private String message;
private ChatMessageType t;

public ChatServer() throws RemoteException {
    super();
}

@Override
public void Message(String sender, ChatMessageType t, String message)
        throws RemoteException {
    this.sender = sender;
    this.message = message;
    this.t = t;
}

@Override
public String getSender() throws RemoteException {
    return sender;
}

@Override
public String getMessage() throws RemoteException {
    return message;
}

@Override
public ChatMessageType getType() throws RemoteException {
    return t;
}

public String ToString() throws RemoteException{
    String strMessage;

    switch (t) {
    case SETUP:
        strMessage = sender + " has entered the conversation.";
        break;
    case TEARDOWN:
        strMessage = sender + " has left the conversation.";
        break;
    case MESSAGE:
        strMessage = sender + ": " + message;
        break;
    default:
        strMessage = "";
    }

    return strMessage;
}

// driver.
public static void main(String arg[]) {
    try {
        ChatServer c = new ChatServer();
        Registry registry = LocateRegistry.createRegistry(1099);
        registry.rebind("Server", c);
        System.out.println("Server bound in registry");
    } catch (Exception e) {
        System.out.println("Server error: " + e.getMessage());
        e.printStackTrace();
    }
}

}

public class ChatClient implements ActionListener {


// static private Socket c;

static ChatMessage obj = null;

// static private ObjectInputStream in;
// static private ObjectOutputStream out;

static private String name;
static private String host;
static private Integer port;


/**
 * Launches this application
 */
public static void main(final String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {

            if (args.length != 3) {
                System.out
                        .println("Client requires exactly three args to run.");
                System.exit(-1);
            }

            name = args[0];
            host = args[1];
            port = new Integer(args[2]);

            final ChatClient application = new ChatClient();
            application.getJFrame().setVisible(true);

            try {
                System.out.println("client: connecting to server...");
                // c = new Socket(host, port);
                obj = (ChatMessage) Naming.lookup("//" + host + ":" + port
                        + "/Server");
                System.out.println("client: connected!");
            } catch (Exception e) {
                System.out.println("client: " + e.getMessage());
                System.exit(-1);
            }

            try {
                // out = new ObjectOutputStream(c.getOutputStream());
                // in = new ObjectInputStream(c.getInputStream());

                // announce to other clients that you're here
                // out.writeObject(new ChatMessage(name,
                // ChatMessageType.SETUP, ""));
                obj.Message(name, ChatMessageType.SETUP, "");
            } catch (Exception e) {
            }

            // set up the client's listener as an anonymous thread that's
            // always running
            // new Thread(new Runnable(){
            // public void run()
            // {
            // while(true)
            // {
            try {
                System.out.println(name + ": waiting for data");
                ChatMessage m = (ChatMessage) Naming.lookup("//" + host
                        + ":" + port + "/Server");
                System.out.println(name + ": data received");
                application.updateTextArea(m.ToString());
            } catch (Exception e) {
            }
            // }
            // }
            // }).start();
        }
    });
}

public void updateTextArea(final String message) {
    conversation.setText(conversation.getText() + message + "\n");

    // this will guarantee that the bottom of the conversation is visible.
    conversation.setCaretPosition(conversation.getText().length());
}

// send button has been pressed, send the message to the server.
public void actionPerformed(ActionEvent e) {
    if (send.getText().equals("Send")) {
        try {
            System.out.println(name + ": sending data");
            // ChatMessage m = new ChatMessage(name,
            // ChatMessageType.MESSAGE, message.getText());
            // out.writeObject(m);
            obj.Message(name, ChatMessageType.MESSAGE, message.getText());
            message.setText(""); // clear the text box.
            System.out.println(name + ": data sent");
        } catch (Exception ex) {
            // TODO Auto-generated catch block
            ex.printStackTrace();
        }
    }
}

}

enum ChatMessageType{
SETUP,
MESSAGE,
TEARDOWN
}public interface ChatMessage extends Remote{

public String getSender() throws RemoteException;
public String getMessage() throws RemoteException;
public ChatMessageType getType() throws RemoteException;
public void Message(String sender, ChatMessageType t, String message) throws RemoteException;
public String ToString() throws RemoteException;

No correct solution

OTHER TIPS

I realize this question is pretty old and you probably figured out an answer for this, but, I thought I'd share an approach I took for going from Java sockets to RMI. Maybe it is useful for others looking to do the same thing.

I basically abstracted out the socket portion into a "Tunnel" object that represents a communication path between hosts. And the tunnel consists of several "channels", that represent a one-way communication between the source and destination.

You can check out more details at my blog here: http://www.thecodespot.com/?p=1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top