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 part
here .
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.
Post your comments and suggestions !!