6 Developing RMI Based Server (ChatServer)

Pravin Jain

epgp books

 

Introduction

 

In the last module, we have learnt about RMI. In this module we will look at how to create an interactive application like chat server using RMI.

 

Demo Of creating ChatServer using RMI.

 

In this demo we will develop a ChatServer. Developing the Chat Server application using the RMI would require the following components.

  • A ChatServer interface, which would be the remote interface
  • A ChatClient interface, which is again another remote interface from client side
  • An implementation of the ChatServer interface (ChatServerImpl)
  • An application to create instance of ChatServer and make it available (ChatServerMain)
  • A GUI implementation of the ChatClient interface (ChatClientGUIImpl)
  • A GUI application for the client side (ChatFrame)

Developing the Chat Server

 

The entire Chat Server will be developed in two modules. This module is the first module and will cover the following components

  • ChatServer interface
  • ChatClient interface
  • ChatServerImpl class
  • ChatServerMain class

In the next module we will develop the GUI client application.

 

Developing the Chat Server interface

 

The ChatServer interface is the Remote interface, and has methods which will be invoked by the client. The following methods are identified as interaction from client to the server.

 

String[] login(ChatClient client), this is used for logging in a ChatClient with the Server, it would return an array containing the names of the other clients who are currently logged in.

String[] list(), this can be used for getting the list names of the clients who are currently logged in.

void sendMessage(String from, , String to, String message), this method can by client for sending a message to another loggedin client.

void sendMessage(String from, String message), this method can be used by client to send message to all the currently loggedin clients.

void logout(String name), this method can be used by a client to logout.

 

A remote interface has to extend from the interface called Remote and all the methods must have a throws for the RemoteException. The code for ChatServer interface is as follows:

 

Source code of ChatServer interface

package org.epgpathshala.dad.rmi.server;

 

import java.rmi.Remote;

import java.rmi.RemoteException;

import org.epgpathshala.dad.rmi.client.ChatClient;

 

public interface ChatServer extends Remote {

String[] login(ChatClient client) throws RemoteException;

String[] list() throws RemoteException;

void sendMessage(String from, String to, String message) throws RemoteException; void sendMessage(String from, String message) throws RemoteException;

void logout(String name) throws RemoteException;

}

Developing the Chat Client interface

 

The ChatClient interface is the Remote interface, and has methods which will be invoked by the server. The following methods are identified as interaction from server to the client.

 

String getName(), this method is used by the server to get the name of the client.

void joined(String name), this method is used by the server to indicate to the client that a new client has logged in.

void left(String name), this method is used by the server to indicate to the client that a client has logged out.

void showMessage(String from, String message), this method is used by the server to ask the client to show a new message, which has been received for that client.

 

A remote interface has to extend from the interface called Remote and all the methods must have a throws for the RemoteException. The code for ChatClient interface is as follows:

 

Source code of ChatClient interface

 

package org.epgpathshala.dad.rmi.client;

 

import java.rmi.Remote;

import java.rmi.RemoteException;

 

public interface ChatClient extends Remote { String getName() throws RemoteException;

void joined(String name) throws RemoteException;

void left(String name) throws RemoteException;

void showMessage(String from, String message) throws RemoteException;

}

Developing the ChatServerImpl

 

The ChatServerImpl class is the implementation of the ChatServer interface. This class, has to extend from the UnicastRemoteObject class of the java.remote.server package, and implement the ChatServer interface (the remote interface developed earlier). This implementation class must have a constructor which has a throws for RemoteException. In our implementation here, the ChatServerImpl maintains all the Remote objects for the logged in ChatClients, name-wise. This is done by using a Map<String, ChatClient>. So, this class used such a map as instance variable, called clientMap.

The implementation of the various methods is as follows:

 

public String[] login(ChatClient client), when this method is invoked by the client, it passes an instance of the ChatClient, this method. The method would get the name of the client and check if another is already loggedin with this name and throw exception, if that is the case, otherwise it would get a list of all the client names in an array and then add the new client in the map. It would then invoke the joined method on all the other loggedin clients to send the name of the new client logging in and then returns the list of all the other client names to the client logging in.

 

public String[] list(), this method is provided for a client to get a list of all the loggedin clients, it does this by get the client names from the clientMap.

 

public void sendMessage(String from, String to, String message), this method is used by a client to send a message to another client. The method fetches the ChatClient object for the recipient client from the clientMap and invokes the show Message method on it.

 

public void sendMessage(String from, String message), this method is used by a client to send a message to all the currently loggedin clients. This method simply gets the list of all the currently loggedin users by using the list method and then invokes the previous methods by using the recipient from the array received from the list.

 

public void logout(String name), when this method is invoked by the client, it passes its name to this method. The method would remve the entry from the clientMap for this client and then gets a list of all the client names in an array and invokes the left method on all the other loggedin clients to send the name of the this client logging out. The code for the ChatServerImpl is as follows:

 

Source code of ChatServerImpl class

package org.epgpathshala.dad.rmi.server;

import java.rmi.Remote;

import java.rmi.RemoteException;

import java.rmi.server.UnicastRemoteObject;

import org.epgpathshala.dad.rmi.client.ChatClient;

import java.util.Map;

import java.util.HashMap;

public class ChatServerImpl extends UnicastRemoteObject implements ChatServer { private Map<String, ChatClient> clientMap = new HashMap<>();

 

public ChatServerImpl() throws RemoteException {

}

public String[] login(ChatClient client) throws RemoteException {

String name = client.getName();

if (clientMap.containsKey(name)) {

throw new RuntimeException(“name already in use”);

}

String[] clientNames = list();

clientMap.put(name, client);

for (String clientName : clientNames) {

clientMap.get(clientName).joined(name);

}

return clientNames;

}

public String[] list() {

return clientMap.keySet().toArray(new String[clientMap.size()]);

}

public void sendMessage(String from, String to, String message) throws RemoteException {

clientMap.get(to).showMessage(from, message);

}

public void sendMessage(String from, String message) throws RemoteException {

String[] clientNames = list();

for (String clientName : clientNames) { sendMessage(from, clientName, message);

}

}

public void logout(String name) throws RemoteException {

clientMap.remove(name);

String[] clientNames = list();

for (String clientName : clientNames) {

clientMap.get(clientName).left(name);

}

}

}

Developing the ChatServerMain

 

The ChatServerMain class contains the main method its only purpose is to create the object of ChatServerImpl and make it available for lookup by a client. The code for ChatServerMain class is as follows:

 

Source code of ChatServerMain class

 

package org.epgpathshala.dad.rmi.server;

 

import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.RemoteException;

 

public class ChatServerMain {

public static void main(String[] args) throws RemoteException {

String chatRoom = args[0];

Registry r = LocateRegistry.createRegistry(1099);

ChatServer server = new ChatServerImpl(); r.rebind(chatRoom, server);

}

}

you can view video on Developing RMI Based Server (ChatServer)
Suggested Reading:
1. Core Java Volume 2 by Cay Horstmann & Gary Cornell, Ninth Edition, Pearson Education.
2. Beginning Java Networking by Alexander V Konstantinou and others, Wrox publication.
3. Java RMI By William Grosso O’Rielly media
4. https://docs.oracle.com/javase/tutorial/rmi/index.html