My place to Speak!

… my little house that gave me a place to talk and share what I had seen, heard, and felt.

March 27, 2010

Simple Chatting Application using Java RMI

Filed under: Programming — Angga Lingga @ 3:23 PM

Since so many visitors come to my blog and searching about creating an application using Java RMI, so now I want to make a new one about simple chatting application using java rmi. I hope my codes free of bugs, but it is unbelievable i think.

Before you continue make this application you must make sure that a JDK has been installed on your computer. If you do not have it before please download JDK from Sun website and install it on your computer.

Now let create the program. I will use Java RMI and make 3 classes and one 1 interface.

  1. ChatImpl (class)
  2. ChatServer (class)
  3. RMIClient (class)
  4. Chatting (interface)

We need Chatting Interface to determine what methods that can be invoked by the client. In this interface i will defines 4 methods that can be invoked by the client.

  • sendPublicMessage => send a message from a client to another client.
  • getClientList => get a numbers of user connected to the server.
  • connect => creating a new socket connection to server.
  • disconnect => terminated connection from server.
/*
File Name : Chatting.java
Author : Angga Lingga
*/

import java.rmi.*;
import java.util.*;

public interface Chatting extends Remote
{
	public void sendPublicMessage(String keyword, String username, String message) throws RemoteException;
	public ArrayList getClientList() throws RemoteException;
	public void connect(String username) throws RemoteException;
	public void disconnect(String username) throws RemoteException;
}

After we determine the methods that can be invoked by the client in the Chatting Interface, now we will create a class that implements the Chatting Interface (for creating the server stub).

/*
File Name : ChatImpl.java
Author : Angga Lingga
*/

import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import java.net.*;

public class ChatImpl extends UnicastRemoteObject implements Chatting
{
	private ChatServer cs;

	public ChatImpl(ChatServer cs) throws RemoteException
	{
		super();
		this.cs = cs;
	}

	public void sendPublicMessage(String keyword, String username, String message) throws RemoteException
	{
		cs.sendPublicMessage(keyword, username, message);
	}

	public ArrayList getClientList() throws RemoteException
	{
		return cs.getClientList();
	}

	public void connect(String username) throws RemoteException
	{
		cs.connect(username);
	}

	public void disconnect(String username) throws RemoteException
	{
		cs.disconnect(username);
	}
}

Now after we create the ChatImpl, we create the server and the client codes.

/*
File Name : ChatServer.java
Author : Angga Lingga
*/

import java.rmi.*;
import java.rmi.server.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.swing.JOptionPane;

public class ChatServer
{
	private static HashMap<String, Socket> connectedUser = new HashMap<String, Socket>();
	private static Socket ClientSocket = null;
	private static ServerSocket serverSocket;
	private static String username = null;
	private static PrintWriter output;

	private static final String PUBLICMESSAGE = "PUBLICMESSAGE";
	private static final String ONLINE = "ONLINE";
	private static final String OFFLINE = "OFFLINE";

	public ChatServer()
	{
		try
		{
			ChatImpl csi = new ChatImpl(this);
			Naming.rebind("rmi://localhost:1099/ChatService", csi);
		}
		catch(java.rmi.ConnectException ce)
		{
			JOptionPane.showMessageDialog(null, "Trouble : Please run rmiregistry.", "Connect Exception", JOptionPane.ERROR_MESSAGE);
			System.exit(-1);
		}
		catch (IOException ioe)
		{
			JOptionPane.showMessageDialog(null, "Trouble : Please run rmiregistry.", "Exception", JOptionPane.ERROR_MESSAGE);
			System.exit(-1);
		}
		catch (Exception e)
		{
			JOptionPane.showMessageDialog(null, "Trouble : Please run rmiregistry.", "Exception", JOptionPane.ERROR_MESSAGE);
			System.exit(-1);
		}
	}

	public static void main (String[] args)
	{
		try
		{
			int port = Integer.parseInt(args[0]);
			ChatServer cs = new ChatServer();
			cs.processConnection(port);
		}
		catch (ArrayIndexOutOfBoundsException ae)
		{
			JOptionPane.showMessageDialog(null, "Please insert the port", "ATTENTION", JOptionPane.INFORMATION_MESSAGE);
			System.exit(-1);
		}
	}

	private void processConnection(int port)
	{
		try
		{
			serverSocket = new ServerSocket(port);
			System.out.println("Server is running on port " + port + " .... ");
		}
		catch (IOException ioe)
		{
			JOptionPane.showMessageDialog(null, "Could not listen port " + port, "ERROR", JOptionPane.ERROR_MESSAGE);
			System.exit(-1);
		}

		try
		{
			while (true)
			{
				addClient(serverSocket.accept());
				String username = getUsername();
				sendPublicMessage(PUBLICMESSAGE, "SERVER", "[" + username + "] is now online");
			}
		}
		catch (IOException ioe)
		{
			JOptionPane.showMessageDialog(null, "Could not accept connection.", "ERROR", JOptionPane.ERROR_MESSAGE);
			System.exit(-1);
		}
	}

	public void connect(String username)
	{
		this.username = username;
	}

	public String getUsername()
	{
		return username;
	}

	public ArrayList getClientList()
	{
		ArrayList myUser = new ArrayList();

		Iterator i = connectedUser.keySet().iterator();
		String user = null;

		while(i.hasNext())
		{
			user = i.next().toString();
			myUser.add(user);
		}

		return myUser;
	}

	public void addClient(Socket clientSocket) throws RemoteException
	{
		connectedUser.put(getUsername(), clientSocket);
		sendPublicMessage(ONLINE, getUsername(), "CLIENT");
	}

	public void sendPublicMessage(String keyword, String username, String message) throws RemoteException
	{
		Iterator i = connectedUser.keySet().iterator();
		String user = null;
		while(i.hasNext())
		{
			try
			{
				user = i.next().toString();
				ClientSocket =  connectedUser.get(user);
				output = new PrintWriter(ClientSocket.getOutputStream(), true);
				output.println(keyword + "***" + username + "***" + message);
				output.flush();
			}
			catch(IOException ioe)
			{
				connectedUser.remove(user);
				sendPublicMessage(OFFLINE, user, user + " has been left the conversation");
			}
		}
	}

	public void disconnect(String username) throws RemoteException
	{
		connectedUser.remove(username);
		sendPublicMessage(OFFLINE, username, username + " has been left the conversation");
		sendPublicMessage(PUBLICMESSAGE, "SERVER", username + " has been left the conversation");
	}
}

 

/*
File Name : RMIClient.java
Author : Angga Lingga
*/

import java.rmi.*;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;

public class RMIClient extends JFrame implements ActionListener, Runnable
{
	private Chatting c;

	private static String ipAddress;
	private int port;
	private BufferedReader in = null;
	private Thread thread;

	private JButton jButtonConnect;
	private JButton jButtonSend;
	private JLabel jLabelUserList;
	private JList jListUser;
	private JScrollPane jScrollPaneListUser;
	private JScrollPane jScrollPaneMessage;
	private JTextArea jTextAreaMessage;
	private JTextField jTextSendMessage;
	private JTextField jTextUserName;

	private Socket socket = null;
	private DefaultListModel listClient;

	private String message;

	private final String SEPARATOR = "\\*\\*\\*";
	private final String PUBLICMESSAGE = "PUBLICMESSAGE";
	private final String ONLINE = "ONLINE";
	private final String OFFLINE = "OFFLINE";

	public RMIClient()
	{
		initComponents();
		thread = new Thread(this);
	}

	@SuppressWarnings("unchecked")
	private void initComponents()
	{
		listClient = new DefaultListModel();
		jScrollPaneMessage = new JScrollPane();
		jTextAreaMessage = new JTextArea();
		jTextUserName = new JTextField();
		jButtonConnect = new JButton();
		jScrollPaneListUser = new JScrollPane();
		jListUser = new JList(listClient);
		jTextSendMessage = new JTextField();
		jButtonSend = new JButton();
		jLabelUserList = new JLabel();

		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setTitle("Chat Client");
		setResizable(false);
		getContentPane().setLayout(null);

		jTextAreaMessage.setColumns(20);
		jTextAreaMessage.setEditable(false);
		jTextAreaMessage.setRows(5);
		jTextAreaMessage.setAutoscrolls(false);
		jScrollPaneMessage.setViewportView(jTextAreaMessage);

		getContentPane().add(jScrollPaneMessage);
		jScrollPaneMessage.setBounds(10, 10, 340, 240);

		jTextUserName.addActionListener(this);
		getContentPane().add(jTextUserName);
		jTextUserName.setBounds(360, 10, 100, 20);

		jButtonConnect.setFont(new java.awt.Font("Times New Roman", 0, 11));
		jButtonConnect.setText("Connect");

		getContentPane().add(jButtonConnect);
		jButtonConnect.setBounds(470, 10, 80, 21);

		jListUser.setToolTipText("List of User");
		jScrollPaneListUser.setViewportView(jListUser);

		getContentPane().add(jScrollPaneListUser);
		jScrollPaneListUser.setBounds(360, 50, 190, 200);

		jTextSendMessage.addActionListener(this);

		getContentPane().add(jTextSendMessage);
		jTextSendMessage.setBounds(10, 260, 340, 30);

		jButtonSend.setFont(new java.awt.Font("Times New Roman", 0, 11));
		jButtonSend.setText("Send");
		jButtonSend.addActionListener(this);

		getContentPane().add(jButtonSend);
		jButtonSend.setBounds(360, 261, 70, 30);

		jLabelUserList.setFont(new java.awt.Font("Arial Black", 0, 11));
		jLabelUserList.setText("User List");
		getContentPane().add(jLabelUserList);
		jLabelUserList.setBounds(360, 30, 55, 17);

		java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
		setBounds((screenSize.width-570)/2, (screenSize.height-330)/2, 570, 330);

		jButtonConnect.addActionListener(this);
		jButtonSend.setEnabled(false);
	}

	public static void main(String args[])
	{
		JFrame.setDefaultLookAndFeelDecorated(true);
		try
		{
			RMIClient rm = new RMIClient();
			rm.setIPAddress(args[0]);
			rm.setPort(Integer.parseInt(args[1]));
			rm.setServer(ipAddress);
			rm.setVisible(true);
		}
		catch (ArrayIndexOutOfBoundsException ae)
		{
			JOptionPane.showMessageDialog(null, "Please insert the port", "ATTENTION", JOptionPane.INFORMATION_MESSAGE);
			System.exit(-1);
		}
	}

	private void setIPAddress(String ipAddress)
	{
		this.ipAddress = ipAddress;
	}

	private void setPort(int port)
	{
		this.port = port;
	}

	private String getIPAddress()
	{
		return ipAddress;
	}

	private int getPort()
	{
		return port;
	}

	private void setServer(String ipAddress)
	{
		try
		{
			c = (Chatting) Naming.lookup("rmi://" + ipAddress + "/ChatService");
		}
		catch (MalformedURLException murle)
		{
			System.out.println();
			System.out.println("MalformedURLException");
			System.out.println(murle);
		}
		catch (RemoteException re)
		{
			System.out.println();
			System.out.println("RemoteException");
			System.out.println(re);
		}
		catch (NotBoundException nbe)
		{
			System.out.println();
			System.out.println("NotBoundException");
			System.out.println(nbe);
		}
		catch (Exception e)
		{
			System.out.println(e);
		}
	}

	public void updateMessage(String username, String message) throws RemoteException
	{
		jTextAreaMessage.append(username + " >> " + message + "\n");
	}

	public void run()
	{
		System.out.println(socket);
		try
		{
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

			while((message = in.readLine()) != null)
			{
				System.out.println(message);
				String[] fromServer = message.split(SEPARATOR);
				if (fromServer[0].equals(ONLINE) || fromServer[0].equals(OFFLINE))
				{
					updateClient(c.getClientList());
				}
				else if (fromServer[0].equals(PUBLICMESSAGE))
				{
					String sender = fromServer[1];
					String content = fromServer[2];
					updateMessage(sender, content);
				}
			}

			in.close();
			socket.close();
		}
		catch(java.net.UnknownHostException e) {}
		catch(IOException e) {}
	}

	public void updateClient(ArrayList allClientList) throws RemoteException
	{
		listClient.clear();
		int i = 0;
		String username;

		for(i=0; i<allClientList.size(); i++)
		{
			username = allClientList.get(i).toString();
			listClient.addElement(username);
		}
	}

	public void actionPerformed(ActionEvent ae)
	{
		if (ae.getActionCommand().equals("Connect") && !jTextUserName.getText().equals(""))
		{
			try
			{
				System.out.println(jTextUserName.getText());
				c.connect(jTextUserName.getText());
				socket = new Socket(ipAddress, port);
				jTextUserName.setEditable(false);
				jButtonConnect.setText("Disconnect");
				System.out.println("You are connect to server");
				thread.start();
				jButtonSend.setEnabled(true);
			}
			catch (RemoteException re) {}
			catch(java.net.UnknownHostException e)
			{
				JOptionPane.showMessageDialog(null, "Can not connect to server " + ipAddress ,"WARNING", JOptionPane.WARNING_MESSAGE);
				System.exit(-1);
			}
			catch(IOException e)
			{
				JOptionPane.showMessageDialog(null, "The server " + ipAddress + " on port " + port + " is not found!", "ERROR",JOptionPane.ERROR_MESSAGE);
				System.exit(-1);
			}
		}
		else if (ae.getActionCommand().equals("Disconnect"))
		{
			try
			{
				c.disconnect(jTextUserName.getText());
				jTextUserName.setText("");
				jTextUserName.setEditable(true);
				listClient.clear();
				jButtonConnect.setText("Connect");
				thread.interrupt();
			}
			catch (RemoteException re) {}
		}
		else if (ae.getSource() == jButtonSend && !jTextSendMessage.getText().equals(""))
		{
			try
			{
				c.sendPublicMessage(PUBLICMESSAGE, jTextUserName.getText(), jTextSendMessage.getText());
				jTextSendMessage.setText("");
			}
			catch (RemoteException re) {}
		}
	}
}

Now after we make the code. Let run the application.

  1. Open your command prompt(under Windows OS).
  2. Compile all the files >>  javac *.java
  3. Compile the ChatImpl.java (it will create a new stub) >> rmic ChatImpl
  4. Run the RMIRegistry >> rmirgistry
  5. You must make sure that your rmiregistrycommand run successfully. If your command does not run, may this command has not recognized by your system yet. If this command does not run, please follow these instructions below (I use Microsoft Windows Vista):
    • Right click on your My Computer and click ‘Properties‘.
    • Click ‘Advanced system settings‘.
    • You must make sure that you already on the ‘Advanced’ tab. Click ‘Environment Variables‘.
    • On the ‘Systems variables‘ section, find ‘Path‘ item and double click and insert your JDK lib directory location on ‘variable value‘ text box. You must make a separator ‘;‘ (without quotes) before insert it (required).
      My JDK lib directory location: ‘C:\Program Files\Java\jdk1.6.0_10\bin
    • Click OK > OK > OK
  6. Open a new command prompt.
  7. Run the server >> java ChatServer YOUR_AVAILABLE_PORT (ex: java ChatServer 4444)
    I hope the response should be like this >> Server is running on port YOUR_AVAILABLE_PORT
  8. Open a new command prompt.
  9. Run a new client >> java RMIClient SERVER_ADDRESS SERVER_PORT (ex: java RMIClient 127.0.0.1 4444)
  10. Insert your name “angga” and client Connect.
    I hope the server response should be like this >> SERVER >> [angga] is now online
    It show that you have connect to server.
  11. Open a new command prompt again.
  12. Run a new client again >> java RMIClient SERVER_ADDRESS SERVER_PORT (ex: java RMIClient 127.0.0.1 4444)
  13. Insert your name “lingga” and client Connect.
    I hope the server response should be like this >> SERVER >> [lingga] is now online
    It show that you have connect to server.
  14. Now you angga and lingga can chat with one server.

You can download the source codes here.

I have develop a new one chatting application using Java RMI too. This application have many server. It allows one client in the different server can talk each other.

Client Chatting

Client Chatting Process

>> java RMIClient SERVER_ADDRESS SERVER_PORT

29 Comments »

  1. Hallo bro…

    Kunjungan perdana nih…..baru tahu blognya bro Lingga….

    Comment by Planet Orange — April 26, 2010 @ 12:09 PM

  2. @Planet Orange
    Hahaha …
    thanks ya bro udah datang kerumah kita yang sederhana ini … :D

    Comment by Angga Lingga — April 26, 2010 @ 12:20 PM

  3. thanks mas, uda aku coba postnya mas yang diatas woooo…. hsilnya keren juga………………………

    tak tunggu postingan yang lainnya mas, tapi tentang java………..

    Comment by aang — June 3, 2010 @ 2:33 PM

  4. @aang yoi sama-sama … iya ntar tak buatin lagi artikel tentan Java. Sering-sering berkunjung ya … :D

    Comment by Angga Lingga — June 3, 2010 @ 2:49 PM

  5. Hi!

    Great RMI example! Helped us a lot!!
    Just one more thing. I think that you should display the RemoteException because in our case the app didn’t work due to the Virtual-Box adapter.

    Thanks a lot,
    Yiannis

    Comment by Yiannis Gkoufas — February 9, 2011 @ 11:24 PM

  6. Thanks great example…but i tried to run it on eclipse and it kept showing me the exception “Attention : insert the port”
    so whats the deal??

    Comment by Nada — April 14, 2011 @ 2:04 AM

  7. @Nada I use Command Prompt to compile and test it. Let me try on Eclipe and I will inform again if have fix this one. Thanks for testing my application :)

    Comment by Angga Lingga — April 16, 2011 @ 2:19 PM

  8. hi,.. i am a student,.. a basic level java programmer,.. very nice shots,…!! I am planning to make a desktop app with java but the database server in the internet,.. would you share what i have to prepare,..? a kind of steps of learning or something like that,…

    Comment by Henn Claus — June 25, 2011 @ 1:41 PM

  9. WOW… WHAT an application … !! really awesome n handy .. :)

    Thanks.

    Comment by Loosu — October 4, 2011 @ 9:27 AM

  10. Hi,

    I try to execute the application in Eclipse at Windows 7, i’m starting the Rmiregistry in a console by the command
    >start rmiregistry &
    and in the other console when i execute de command :
    >java ChatServer N° Port
    it give me a problem that “Trouble : Please run rmiregistry”

    Thanks for your interesting code and please response me in the shortest delay

    Comment by Salvan — December 30, 2011 @ 10:49 PM

  11. I’m so sorry but I use EditPlus when I code this program so I don’t know the problems when you run it by using Eclipse or another IDE.

    Anyway I will try to help you and inform you ASAP when I get the answer.

    Comment by Angga Lingga — February 14, 2012 @ 6:35 AM

  12. Hii, This is nice tuorial and i successfully implemented it. But how can i implement for desktop .Please give me suggestion and give any good link.

    Comment by Shivam Saxena — August 1, 2012 @ 9:58 AM

  13. Hii, This is nice tuorial and i successfully implemented it. But how can i implement for desktop .Please give me suggestion and from where we can read proper documentation for chatting application.

    Comment by Shivam Saxena — August 1, 2012 @ 10:00 AM

  14. Thanks for this code

    Comment by Rakesh Parte — April 10, 2013 @ 2:12 AM

  15. Nice article. It’s a shame the source download is on a popup-fest farm website.

    Comment by DJ — July 16, 2013 @ 10:56 PM

  16. hey,
    this is exactly what i am looking for
    but i am not allowed to use socket
    i can only use rmi
    i need to make a server client chat where there are many clients and one server
    clients can chat among each other via server i.e client1 sends a message along with ip of client2 to the server and the server forwards this meassage to client2 using the ip address provided by client1
    i am just stuck on this portion i dont know to does the server sends the message to any client using its ip
    and one more thing the client cannot be made a server in itself
    sorry school project limitations

    Comment by bhakti — July 28, 2013 @ 12:31 AM

  17. Develop an RMI application for chatting between client and server , the chatting should stop when both of them say “bye

    Comment by ana — September 16, 2013 @ 4:22 PM

  18. this is not my comment….this is my question…….

    Comment by ana — September 16, 2013 @ 5:03 PM

  19. i am not able to connect through intranet

    Comment by kishore — September 17, 2013 @ 2:13 PM

  20. i am not able to connect through intranet from different system

    Comment by kishore — September 17, 2013 @ 2:13 PM

  21. When I try to run the server, I get Trouble: Please run rmiregistry
    And I already have rmiregistry running
    Is there a specific port that the rmiregistry is running at?
    Please Help

    Comment by Jad — November 5, 2013 @ 6:42 AM

  22. I tried it with command prompt and i got the same msg

    Comment by Jad — November 5, 2013 @ 6:45 AM

  23. when i try….i saes enter port no…
    what to do???

    Comment by kumar — January 9, 2014 @ 11:16 PM

  24. Awesome application,thanks for the help

    Comment by James — February 4, 2014 @ 12:59 AM

  25. thanks alot……bro….this article helpfull for me

    Comment by sagar mal — February 18, 2014 @ 11:22 AM

  26. Hi,
    Thanks for the code.
    I was trying to run the code on different machine but i’m unable to make connections on different machines.
    The code runs very well on localhost but on separate pc’s RMIClient is unable to make connections

    Comment by Manish — April 23, 2014 @ 10:13 PM

  27. Hi,
    Thanks for the code.
    I was trying to run the code on different machine but i’m unable to make connections on different machines.
    The code runs very well on localhost but on separate pc’s RMIClient is unable to make connections
    Please troubleshoot the problem asap

    Thanks

    Comment by Manish — April 23, 2014 @ 10:14 PM

  28. hey,
    this is exactly what i am looking for
    but i am not allowed to use socket
    i can only use rmi
    i need to make a server client chat where there are many clients and one server
    clients can chat among each other via server i.e client1 sends a message along with ip of client2 to the server and the server forwards this meassage to client2 using the ip address provided by client1
    i am just stuck on this portion i dont know to does the server sends the message to any client using its ip
    and one more thing the client cannot be made a server in itself
    sorry school project limitations

    Comment by Name * — May 6, 2014 @ 2:20 PM

  29. Everytime i tried to run this program it asks me for the port

    Comment by Carlos — July 2, 2014 @ 11:42 AM

RSS feed for comments on this post. TrackBack URL

Leave a comment

© 2009 Angga Lingga | Powered by WordPress