This tutorial is about creating a chat application using java RMI , Socket connection and java swing . First let’s take a look at the functionalities we will be creating in this chat application. You can read the first parthere .
This chat application will have two parts ( client and server ) . The server will be running as rmi server. Whenever a client connects to server , it will first authenticate the client (client can register himself on the server ) After successful authentication , the client will be shown friend’s list , so that he can chat to his friends. Whenever a friend becomes online or offline , the client is notified and friends list changes dynamically .
Server stores user list and friends list in it's internal database. When the client connects to rmi server , it provides it’s ip also which is saved by rmi server. When a client start chat with online friend , the rmi server issues a remote call to start a socket connection to transfer chat messages . So rmi server here does not store or save chat . The chat messages are transferred directly between the clients by using socket connection between them.
In this part of tutorial , we will create a RMI Server and client interface which will be called by RMI Server.
so these is our RMI Server :
/** * Application Name :- Let's Chat * @(#)RMIServer.java * * * @author abhishek somani * @version 1.00 2008/4/7 * * Main server where user have registered and creating port for this application */ import java.rmi.*; import java.rmi.server.*; import java.io.*; import java.rmi.registry.*; public class RMIServer { public static void main(String args[])throws IOException { //System.out.println("enter rmi port number"); startRegistry(1099); // register exported object to naming directory RegInterface_Impl obj=new RegInterface_Impl(); String url = "rmi://localhost:"+1099+"/reg"; try { Naming.bind(url,obj); } catch(Exception e) { System.out.println(e.getMessage()); } } public static void startRegistry(int portNo)throws RemoteException { try { Registry r = LocateRegistry.getRegistry(portNo); r.list(); } catch(RemoteException e) { System.out.println("registery not created\n"); Registry r = LocateRegistry.createRegistry(portNo); r.list(); System.out.println("registery created\n waiting for connection"); } } }Here , we have started the rmi registry , and exposed the RegInterface object , which will be used by client to make remote calls to server. Here is RegInterface which will contain methods to be called by client :
/** * Application Name :- Let's Chat * * @(#)RegInterface.java * * * @author abhishek somani * @version 1.00 2008/4/12 * * */ import java.rmi.*; public interface RegInterface extends Remote { public boolean register(ClientInterface obj)throws RemoteException; // validate and register to client to application public String getFrendIP(String uname)throws RemoteException; // give friendlist public String test()throws RemoteException; public void Signingout(String uname) throws RemoteException; // Signout from the application }Here , in the register method , client will pass its remote interface to server , so that server can call remote methods on client . Here is ClientInterface
/** * Application Name :- Let's Chat * Team Name :- Insomniac * * * @author abhishek somani * @version 1.00 2008/4/9 * * */ import java.rmi.*; import java.util.*; public interface ClientInterface extends Remote { public String getUsername()throws RemoteException; public String getPassword()throws RemoteException; // server will get username and password public void startChatServer()throws RemoteException; // server will start client socket public String getIp()throws RemoteException; //gives ip to server public void frendList(Vector frend)throws RemoteException; //get friend list on login public void closeChatServer() throws RemoteException; //closing clientsocket public void notifyOnline(String uname)throws RemoteException; // notify if any new friend is online public void removeFrend(String uname)throws RemoteException; // remove from list if any logout }Here this clientInterface contains all the methods to start and stop socket connection on its part , and also methods to modify friends list dynamically whenever a friend become online or offline . Here is the implementation of client interface which will reside with Client application , Server application will have the interface only and stub class of this interface(ClientInterface_Impl_Stub.class and ClientInterface.class)
/** * Application Name :- Let's Chat * Team Name :- Insomniac * @(#)ClientInterface.java * * * @author abhishek somani:200501077 & Anurag Jain:200501027 * @version 1.00 2008/4/15 * * After correct Login userInterface Providing online user friends and signout option * with the application logo */ import java.util.*; import java.rmi.*; import java.rmi.server.*; public class ClientInterface_Impl extends UnicastRemoteObject implements ClientInterface { private String username; private String password; private String ip=""; public static Vector frendList; public static Vector friends; public ServerS t ; public Repaint obj; public ClientInterface_Impl(String u ,String p, String ipAdress) throws RemoteException { super(); username=u; password=p; ip=ipAdress; frendList=new Vector(); obj=new Repaint(); t= new ServerS(); } public String getUsername()throws RemoteException { return username; } public String getPassword()throws RemoteException { return password; } public String getIp()throws RemoteException { return ip; } public void frendList(Vector frend)throws RemoteException { friends = frend; //System.out.println("friend added"); Object f[]; try { f=frend.toArray(); obj.temp(this,f); } catch(Exception e) { System.out.println("exception in repaint call"); e.printStackTrace(); } } // open the client socket to accept request for chating send by the other friend public void startChatServer()throws RemoteException { //System.out.println("in start chat"); t.uname=username; t.start(); } public void closeChatServer() throws RemoteException { try { //System.out.println("in stop chat"); t.conSocket.close(); t.stop(); //System.out.println("Socket Close"); } catch(Exception e) { System.out.println("Exception in closing server socket "); } } // when user get online notify all the friends who are online public void notifyOnline(String uname)throws RemoteException { try { friends.add(uname); friends.trimToSize(); obj.addButtons(); //System.out.println("calling add button function\n"); Object fi[]; fi=friends.toArray(); obj.temp(this, fi); } catch(Exception e) { System.out.println("exception in clientINterfaceImpl adding new buttons\n"); System.out.println(e.getMessage()); e.printStackTrace(); } } // after logout remove the username from the friends user list public void removeFrend(String uname) { try { friends.remove(uname); friends.trimToSize(); obj.removeButton(uname); //System.out.println("calling remove button function\n"); Object fi[]; fi=friends.toArray(); obj.temp(this,fi); } catch(Exception e) { System.out.println("exception in clientINterfaceImpl adding new buttons\n"); System.out.println(e.getMessage()); e.printStackTrace(); } } }Here is the implementation of RegInterface .
/** * Application Name :- Let's Chat * Team Name :- Insomniac * @(#)RegInterface_Impl.java * * * @author abhishek somani: * @version 1.00 2008/4/7 * * Implementation of the register interface */ import java.rmi.*; import java.rmi.server.*; import java.util.*; import java.sql.*; public class RegInterface_Impl extends UnicastRemoteObject implements RegInterface { public Vector clientList; public boolean flag; public Vector frends; Enumeration clientObj, e , clientObj1; boolean check; MySqlCon database; ResultSet result=null; public RegInterface_Impl()throws RemoteException { super(); clientList = new Vector(); } // validate the username and password on the ServerSide // if username and password match then true otherwise false // username and password doesn't match public synchronized boolean register(ClientInterface obj)throws RemoteException { frends = new Vector(); flag=validateLogin(obj); //System.out.println(flag); if(flag==true) { //System.out.println("in register"); getOnline(obj); /* enter IP address of user in database*/ frends=getFrends(obj); // getting freindlist if((clientList.size()) == 0) { clientList.add(obj); obj.startChatServer(); obj.frendList(frends); //System.out.println("object added successfully"); imOnline(obj,frends); /* send every friend that i am online */ } else { clientList.add(obj); obj.startChatServer(); obj.frendList(frends); // System.out.println("object added successfully"); imOnline(obj,frends); /* send every friend that i am online */ } return flag; } else { //System.out.println("false"); return false; } } // Return Ip of the friend to make socket connection on the client side public String getFrendIP(String username)throws RemoteException { String ip=""; /* thid function will fetch IP of given username from database*/ try { // database connection to get user friendlist database = new MySqlCon(); Connection con = database.getConnection(); String query = "SELECT * FROM user_details WHERE userid = '" + username + "'"; //System.out.println(query); Statement stmt =con.createStatement(); result=stmt.executeQuery(query); if(result.next()) { ip=result.getString("ip"); } } catch(Exception e) { System.out.println("exception in getFrendIp in rmi Server"); } return ip; } public String test()throws RemoteException { return ""; } // validate login whether username exist or not and username and password match or not public boolean validateLogin(ClientInterface obj) { try { String user = obj.getUsername(); String pass = obj.getPassword(); boolean flag=true; // database connection result=null; Statement stmt; Connection con=null; database = new MySqlCon(); con = database.getConnection(); //System.out.println("got connectoin\n"); //System.out.println("user : " + user); String query = "SELECT * FROM user_details WHERE userid = '" + user + "'"; //System.out.println(query); stmt =con.createStatement(); result=stmt.executeQuery(query); //System.out.println("Query Executed"); if(result.next()) { //System.out.println("Users in the Database"); String userid = result.getString("USERID"); String pword = result.getString("PWORD"); if(userid.equals(user) && pword.equals(pass)) { //System.out.println("User Exist in database"); return true; } else return false; } else return false; } catch(Exception e) { System.out.println("Error Occured in Validate Login"); return false; } } // update the status of recently login user as a online public void getOnline(ClientInterface obj) { try { String ip= obj.getIp(); String user = obj.getUsername(); String pass = obj.getPassword(); result=null; Statement stmt; Connection con=null; database = new MySqlCon(); con = database.getConnection(); //System.out.println("got connection\n"); //System.out.println("user : " + user); String query = "update user_details set ip="+"'"+ip+"'"+"WHERE userid = '" + user + "'" ; String query2= "update user_details set online_status="+"'"+"yes"+"'"+"WHERE userid = '" + user + "'" ; //System.out.println(query); stmt =con.createStatement(); stmt.executeUpdate(query); stmt.executeUpdate(query2); } catch(Exception e) { System.out.println(e.getMessage()); } } // return list of the online friends public Vector getFrends(ClientInterface obj) { String user; Vector frends= new Vector(); try { user = obj.getUsername(); int size=0; result=null; Statement stmt; Connection con=null; database = new MySqlCon(); con = database.getConnection(); //System.out.println("got connectoin\n"); String query="select * from frends where userid= "+"'"+user+"' and frend_id in(select userid from user_details where online_status='yes')"+" and status=1"; stmt =con.createStatement(); result=stmt.executeQuery(query); while(result.next()) { size++; } String f; int i=0; ResultSet rs=stmt.executeQuery(query); while(rs.next()) { f=rs.getString("frend_id"); frends.add(f); } //System.out.println("giving client's frend list\n"); /* after client logout have to remove this vector*/ } catch(Exception e) { System.out.println("exception in frendList function"); e.printStackTrace(); System.out.println(e.getMessage()); } return frends; } // calls when user is signout do some certain works // remove from other online friends list // set status as offline in database // makind Ip null in the database public synchronized void Signingout(String uname) { try { result=null; Statement stmt; Connection con=null; database = new MySqlCon(); con = database.getConnection(); //System.out.println("got connectoin\n"); //System.out.println("user : " + uname); String query = "update user_details set ip="+"''"+" WHERE userid = '" + uname + "'" ; String query2= "update user_details set online_status="+"'"+"no"+"'"+"WHERE userid = '" + uname + "'" ; stmt =con.createStatement(); stmt.executeUpdate(query); stmt.executeUpdate(query2); Vector tmp=null; clientObj=clientList.elements(); while(clientObj.hasMoreElements()) { ClientInterface o=(ClientInterface)clientObj.nextElement(); //System.out.println("in vector clientList"+o.getUsername()+"\n"); if(uname.equals(o.getUsername())) { //System.out.println("User's object is found: "+o.getUsername()); tmp=getFrends(o); /* do call back */ o.closeChatServer(); check = clientList.remove(o); clientList.trimToSize(); //System.out.println("Client object is deleted: " + check); break; } } if(tmp!=null) { e= tmp.elements(); clientObj1=clientList.elements(); while(e.hasMoreElements()) { String u = (String)e.nextElement(); while(clientObj1.hasMoreElements()) { ClientInterface o1=(ClientInterface)clientObj1.nextElement(); if(u.equals(o1.getUsername())) { //System.out.println("this frend is found in vector"+o1.getUsername()); /* do call back beta */ //System.out.println("giving notification of :"+user.getUsername()+"to :"+o.getUsername()); o1.removeFrend(uname); break; } } } } //System.out.println(query); //System.out.println(query2); //System.out.println("query succesfully executed"); } catch(Exception e) { System.out.println("Exception in Signingout"); e.printStackTrace(); System.out.println(e.getMessage()); } } public void imOnline(ClientInterface user,Vector frends)throws RemoteException { String userid=user.getUsername(); /*frends vector should be used */ //System.out.println("number of frends are:"+frends.size()); Enumeration frend = frends.elements(); Enumeration clientObj=clientList.elements(); try { while(frend.hasMoreElements()) { String f=(String)frend.nextElement(); while(clientObj.hasMoreElements()) { ClientInterface o=(ClientInterface)clientObj.nextElement(); if(f.equals(o.getUsername())) { //System.out.println("this frend is found in vector"+o.getUsername()); //System.out.println("giving notification of :"+user.getUsername()+"to :"+o.getUsername()); o.notifyOnline(user.getUsername()); break; } } } } catch(Exception e) { System.out.println("exception in imonline"); System.out.println(e.getMessage()); e.printStackTrace(); } } }So that is how we create a simple RMI chat application by using socket connections and remote method calls. UPDATE : You can download the full source code from the following link . LINK Post your comments and suggestions !!