You are on page 1of 19

1! of !

19
Project 2: Distributed Chat Service
Cpre: 550
Instructor: Yong Guan
Ziji Guo
Introduction:
During this project, I built a distributed chat rooms service by using Java RMI. This
whole system could have multiple chatrooms and multiple users. Every user could join the any
available chatroom with the command. Users could see others talking in the same chatrooms,
once the message is received by others, the system will show the received.
Design:
I have seven classes in total, server interface (chatserver_IF.java), client interface
(chatclient_IF.java), two clients class (chatclient_driver.java, chatclient.java), two server class
(chatserver_driver.java , chatserver.java) and one class to store the necessary information for
users (information.java). Both chatserver.java and chatclient.java are extending the
unicastRemoteObject class and implements their interface. chatserver_driver class build the
basic environment and set up everything by calling the naming function and chatserver.java.
Users could register a new chatroom or unregister an available chatroom,view the list of
chatrooms and the information of the selected chatroom by calling the chatserver_driver.java.
The chatclient_driver class could connect to the server, list the current chatrooms and join the
selected chatroom, users could quit the current chatroom and join another chatroom as well.
Server Interfaces (chatserver_IF):
To register the chat server
public void registerChatClient(chatclient_IF chatclient) throws RemoteException;
To get the room list
public Vector getroomname() throws RemoteException;
To join the selected chatroom
public int signIn(String s) throws java.rmi.RemoteException;
To broadcast the message
public void broadcast(String s ) throws java.rmi.RemoteException;
To register the chatroom
public int register(String name, String information) throws RemoteException,
MalformedURLException, NotBoundException;

Page 1! of 19
!

2! of !19
To unregister the chatroom
public void unregister(String name) throws RemoteException, MalformedURLException,
NotBoundException;
To Purge all stored information from the registry
public void reset()throws RemoteException, MalformedURLException,
NotBoundException;
To quit the current chatroom
public boolean signout(String s,chatclient_IF chatclient) throws
java.rmi.RemoteException;
To get the users list
public String getusers()throws java.rmi.RemoteException;
To get the information of selected room
public String getinfo(String roomname) throws RemoteException;
Client Interfaces (chatclient_IF):
To make sure the message has been sent and received successful.
void retrieveMessage( String message) throws RemoteException;

How to Run:
To test the program I used the following command.
rmiregistry
java chatclient_driver
java chatserver_driver
java chatclient Users name
and the followings are the source codes and the screen shots
Source codes:
Chatclient_IF.java :
package chatroom;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface chatclient_IF extends Remote{
void retrieveMessage( String message) throws RemoteException;
}

Page 2! of 19
!

3! of !19
Chatserver_IF.java :
package chatroom;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Vector;
import chatroom.chatclient_IF;
public interface chatserver_IF extends Remote {
public void registerChatClient(chatclient_IF chatclient) throws RemoteException;
public Vector getroomname() throws RemoteException;
public int signIn(String s) throws java.rmi.RemoteException;
public void broadcast(String s ) throws java.rmi.RemoteException;
public int register(String name, String information) throws RemoteException,
MalformedURLException, NotBoundException;
public void unregister(String name) throws RemoteException, MalformedURLException,
NotBoundException;
public void reset()throws RemoteException, MalformedURLException,
NotBoundException;
public boolean signout(String s,chatclient_IF chatclient) throws
java.rmi.RemoteException;
public String getusers()throws java.rmi.RemoteException;
public String getinfo(String roomname) throws RemoteException;
}

chatserver_driver.java :
package chatroom;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
Page 3! of 19
!

4! of !19
import java.rmi.registry.Registry;
import java.rmi.server.RemoteRef;
import java.util.ArrayList;
import chatroom.chatserver;
public class chatserver_driver{
private static ArrayList<information> infolists;
public static void main(String[] args) throws InterruptedException, IOException,
NotBoundException {
// TODO Auto-generated method stub
BufferedReader dataIn = new BufferedReader (new
InputStreamReader(System.in));
String strChoice;
String temp = "localhost";
chatserver server = new chatserver("chatserver","root");
Registry registry = LocateRegistry.getRegistry();
if(args.length>=1){
temp = args[0];
}
int choice=0;
//System.setProperty("java.rmi.server.hostname",temp);
infolists = new ArrayList<information>();
RemoteRef location = server.getRef();
System.out.println(location.remoteToString());
try {
System.out.println("chatserverdriver naming");
Naming.rebind("RMIchatserver", server);
//registry.rebind("RMIchatserver", server);
String chatserverurl = "rmi://"+temp+"/RMIchatserver";
System.out.println("chatclientdriver naming");
chatserver_IF chatserver =
(chatserver_IF)registry.lookup("RMIchatserver");
// System.out.println("chatclientdriver
naming"+chatserver.getroomname());
//
//
while(choice!=5)
{
//menu for registration
System.out.println("Menu:");
Page 4! of 19
!

5! of !19
System.out.println("\t1.Register");
System.out.println("\t2.Un Register");
System.out.println("\t3.List of Chat Rooms");
System.out.println("\t4.Inoformation");
System.out.println("\t5.Quit");
System.out.print("Enter your choice :");
strChoice = dataIn.readLine();
choice = Integer.parseInt(strChoice);
switch (choice)
{
case 1: //register the chatroom with name and information
System.out.print("Enter Room name : ");
String name = dataIn.readLine();
System.out.print("Enter Information : ");
String info = dataIn.readLine();
information infotemp = new information(name,info);
chatserver.register(name, info);
infolists.add(infotemp);
break;
case 2: //unregister the selected chatroom, if not exsisted the
system would list the current chatrooms
System.out.print("Enter Room name : ");
name = dataIn.readLine();
if(infolists.remove(IndexOflist(name)) != null){
chatserver.unregister(name);}
else {
System.out.println("cannot find the chatroom,
please re-enter the name\n following are the current
chatrooms"+chatserver.getroomname().toString());
}
break;
case 3://Show the list of Chat rooms
System.out.println("\nList of Chat rooms");
System.out.println("\t" + chatserver.getroomname().toString());
break;
case 4://lis the Information of the selected Chatroom
System.out.print("Enter Room name : ");
name = dataIn.readLine();
Page 5! of 19
!

6! of !19
String m = infolists.get(IndexOflist(name)).getinfo().toString();
System.out.println("Information of Room " +name + ": " + m);
break;
case 5: //exit the program
chatserver.reset();
System.out.println("rooms:"+chatserver.getroomname().toString());
System.exit(0);
default :
System.out.println("Invalid response");
}
}
}
catch (NumberFormatException e)
{
System.out.println("Invalid response/choice" + e.getMessage());
}
}

public static int IndexOflist(String name){


int i=0;
System.out.println("remove begin--- list size:"+infolists.size());
while(i<infolists.size()){
System.out.println("list's name:"+infolists.get(i).getname()+" target:"+
(name));
if(infolists.get(i).getname().equals(name)){
System.out.println("remove from infolists successful");
return i;
}
else{
i++;
}
}
System.out.println("remove from infolists failed");
return -1;
}
public ArrayList<information> getlists(){
return infolists;
}

Page 6! of 19
!

7! of !19
}

Chatserver.java :
package chatroom;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Vector;
import chatroom.chatclient_IF;
public class chatserver extends UnicastRemoteObject implements chatserver_IF{

private static final long serialVersionUID = 1L;


private ArrayList<String> Users;
private Vector rooms;
private Vector info;
private String name;
public String message;
private ArrayList<chatclient_IF> chatclients;
protected chatserver(String name, String info) throws RemoteException,
MalformedURLException, NotBoundException {
super();
rooms = new Vector();
this.info = new Vector();
this.name = name;
Users = new ArrayList<String>();
//chatclients = new ArrayList<chatclient_IF>();
chatclients = new ArrayList<chatclient_IF>();
System.out.println("creating server :"+name+" "+" "+info);
}
public String getinfo(String roomname) throws RemoteException{
String result ="information cannot found";
Page 7! of 19
!

8! of !19
for(int i=0;i<rooms.size();i++){
if(rooms.get(i).toString().equals(roomname)){
result= (String) info.get(i);
}
}
return result;
}
@Override
public void registerChatClient(chatclient_IF chatclient)throws RemoteException {
// TODO Auto-generated method stub
System.out.println("chatserver registerchatclient");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.chatclients.add(chatclient);
}
public int signIn(String s) throws java.rmi.RemoteException{
Users.add(s);
return 1;
}
public boolean signout(String s,chatclient_IF chatclient) throws
java.rmi.RemoteException{
this.chatclients.remove(chatclient);
return Users.remove(s);
}
public void broadcast(String s) throws java.rmi.RemoteException
{
System.out.println("chatserver boradcast:"+s+" client's size:"+chatclients.size());
System.out.println(chatclients.size());
int i=0;
while(i<chatclients.size()){
System.out.println(chatclients.size()+" -----current:"+i);
chatclients.get(i).retrieveMessage(s);
message=message+"\n"+Users.get(i)+": "+s;
System.out.println(message);
Page 8! of 19
!

9! of !19
i++;
}
}
//get the broadcast message
public String getusers()throws java.rmi.RemoteException
{
return Users.toString();
}
public int register(String name, String information) throws RemoteException,
MalformedURLException, NotBoundException {
// TODO Auto-generated method stub
System.out.println("registering room: "+ name);
rooms.add(name);
info.add(information);
return rooms.size();
}
public void unregister(String name) throws RemoteException, MalformedURLException,
NotBoundException {
// TODO Auto-generated method stub
System.out.println("unregistering room: "+ name);
int i=0;
for(;i<rooms.size();i++){
if(rooms.get(i).toString().equals(name)){
rooms.remove(i);
info.remove(i);
}
}
}
@Override
public Vector getroomname() throws RemoteException {
// TODO Auto-generated method stub
return rooms;
}
@Override
public void reset() {
// TODO Auto-generated method stub
this.rooms.clear();
Page 9! of 19
!

! of !19
10
this.info.clear();
this.Users.clear();
message=null;
}

chatclient_driver.java:

package chatroom;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import chatroom.chatserver;
import chatroom.chatserver_IF;
public class chatclient_driver {
//first parameter is the name of user, the second parameter is the IP address
public static void main(String[] args) throws MalformedURLException,
RemoteException, NotBoundException, InterruptedException {
// TODO Auto-generated method stub
String username="";
String temp = "localhost";
if(args.length>1){
temp = args[1];
}
username = args[0];
String chatserverurl = "rmi://"+temp+"/RMIchatserver";
System.out.println("chatserverurl:"+chatserverurl);
for(int a=0;a<args.length;a++){
Page 10
! of 19
!

! of !19
11
System.out.println("args"+a+":"+args[a]);
}
BufferedReader dataIn = new BufferedReader (new
InputStreamReader(System.in));
String strChoice;
int choice=0;
boolean connection_stastus=false;
try{
System.out.println("chatclientdriver naming");
chatserver_IF chatserver =
(chatserver_IF)Naming.lookup(chatserverurl);
try {
while(choice!=3)
{
//menu for registration
System.out.println("chatroom Menu:");
System.out.println("\t1.List");
System.out.println("\t2.Join");
System.out.println("\t3.Quit");
System.out.print("Enter your choice :");
strChoice = dataIn.readLine();
choice = Integer.parseInt(strChoice);
switch (choice)
{
case 1:
//Show the list of current chatrooms
for(int i=0;i<chatserver.getroomname().size();i++)
{
System.out.println("\nList of Chat rooms
and Informations\n "+chatserver.getroomname().get(i).toString()
+":"+chatserver.getinfo(chatserver.getroomname().get(i).toString()));
}
break;
case 2:
//Join the selected chatroom
System.out.print("Enter Room name : ");
String name = dataIn.readLine();
for(int i=0;i<chatserver.getroomname().size();i++)
{
if(chatserver.getroomname().get(i).toString().equals(name)){
Page !11 of !19

! of !19
12
connection_stastus=true;
}
}
if(connection_stastus){
try{
System.out.println("chatclientdriver thread, user name is :"+username);
System.out.println("Connected to
Chat room :" +name);
chatclient tempclient =new
chatclient(username,chatserver,name);
System.out.println("done by
talking with Chatroom :" +name);
}catch(Exception e){}
}
else{
System.out.println("cannot find the room,
the room list is:"+chatserver.getroomname().toString());
}
break;
case 3: //quit
System.out.println("Quiting Chatroom
Program...");
System.exit(0);
break;
default :
System.out.println("Invalid response");
}
}
}
catch (NumberFormatException e)
{
System.out.println("Invalid response/choice" + e.getMessage());
}
} catch (Exception e) {
System.out.println("Chat server err: " + e.getMessage());
e.printStackTrace();
}
}

Page 12
! of 19
!

! of !19
13

chatclient.java:
package chatroom;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Scanner;
import chatroom.chatserver_IF;
public class chatclient extends UnicastRemoteObject implements chatclient_IF{
/**
*
*/
private static final long serialVersionUID = 1L;
private chatserver_IF chatserver;
private String name=null;
private String roomname="";
private String roomname_def="";
private boolean sttus=true;
protected chatclient(String name, chatserver_IF chatserver,String room) throws
RemoteException, InterruptedException {
System.out.println("chatclient initial");
this.roomname=room;
roomname_def = roomname;
this.name=name;
this.chatserver = chatserver;
System.out.println("name:"+ this.name+" room name:"+roomname+" room list:"+
chatserver.getroomname().toString());
chatserver.registerChatClient(this);

//

Scanner scan = new Scanner(System.in);


String message="";
if(!sttus){System.out.println("stoped");Thread.currentThread().interrupt();return;}

Page 13
! of 19
!

! of !19
14
System.out.println("chatclientdriver runing");
// TODO Auto-generated method stub
try {
chatserver.signIn(name);
System.out.println(chatserver.getusers());
} catch (RemoteException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true){
message = scan.nextLine();
if(message.equals("QUIT")){
System.out.println("----------------------------");
chatserver.signout(name,this);
System.out.println(chatserver.getusers());
break;
}
else{
try {
chatserver.broadcast(roomname+"/"+name
+":"+message);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

// TODO Auto-generated constructor stub


public boolean getstatus(){
return sttus;
}
@Override
public void retrieveMessage(String message) throws RemoteException {
// TODO Auto-generated method stub
Page 14
! of 19
!

! of !19
15
if(message.indexOf(roomname)==0){
//System.out.println("received:"+message+" room:"+roomname+"
num:"+message.indexOf(roomname));}
System.out.println("received:"+message);}
}
}

information.java:
package chatroom;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Vector;
public class information {
private String name;
private String info;
private ArrayList<String> users;
private chatserver server;
information(String name, String info) throws MalformedURLException, RemoteException,
NotBoundException{
this.name=name;
this.info=info;
users = new ArrayList<String>();
}
public String adduser(String user){
users.add(user);
return user;
}
public ArrayList<String> getuser(){
return users;
}
public String getname(){
return name;
}
public String getinfo(){
return info;
}
}

Page 15
! of 19
!

! of !19
16

Test run:
Registering the chatroom
At the beginning check if there was any client room existed, then add the room:cpre with
information Computer engineering, and checked the list if we successful. creating the second
room:ee with information electrical engineering, and check the list as well.

Page 16
! of 19
!

! of !19
17
Next, we are trying to removed the room:ee, after the command works, check the list to see if
there was ee room. Then re-register the room:ee, and create successfully.

Page 17
! of 19
!

! of !19
18
To see if there could be two rooms have same name.

Page 18
! of 19
!

! of !19
19
Start Chatting:
Two users join the same room:cpre, and start talking to see if users could received each
others message. and Type QUIT to quit the chatroom and join another room:ee. In room:ee,
the room:cpre would not see the message in ee.

Conclusion
During the talking, we could see, if the message received by other people in the chat
room, the server would add a received in front of the message. For the latency measurements
by having a client repeatedly register and immediately unregister a chat room, and then measure
the elapsed time. As the measurements, the program runs well, and there is no obvious latency
appear. The number of rooms do not have effect on the latency , or I might need to create more
rooms to see the latency appear.

Page 19
! of 19
!

You might also like