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.
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.
/*
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.
javac *.javarmic ChatImplrmirgistryrmiregistry command 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):
C:\Program Files\Java\jdk1.6.0_10\bin‘java ChatServer YOUR_AVAILABLE_PORT (ex: java ChatServer 4444)Server is running on port YOUR_AVAILABLE_PORT
java RMIClient SERVER_ADDRESS SERVER_PORT (ex: java RMIClient 127.0.0.1 4444)java RMIClient SERVER_ADDRESS SERVER_PORT (ex: java RMIClient 127.0.0.1 4444)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.
java RMIClient SERVER_ADDRESS SERVER_PORT
Hallo bro…
Kunjungan perdana nih…..baru tahu blognya bro Lingga….
@Planet Orange
Hahaha …
thanks ya bro udah datang kerumah kita yang sederhana ini …
thanks mas, uda aku coba postnya mas yang diatas woooo…. hsilnya keren juga………………………
tak tunggu postingan yang lainnya mas, tapi tentang java………..
@aang yoi sama-sama … iya ntar tak buatin lagi artikel tentan Java. Sering-sering berkunjung ya …
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
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??
@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
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,…
WOW… WHAT an application … !! really awesome n handy ..
Thanks.
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
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.