Further Java Practical Class
In order to gain a star in the mark sheet you must complete this exercise. Completing the exercise does not gain you any credit in the examination. In this exercise you will extend your implementation of the Java chat server from Workbook 5 to allow chat session data to be shared or federated between two or more Java chat servers. Sharing of chat session data between servers may be desireable in order to improve scalability or as a basis for supporting more advanced features such as permitting clients to send local as well as global messages (something you're welcome to explore, but is not necessary for this tick).
Copy your implementation for Ticklet 5 into
uk.ac.cam.crsid.fjava.tick5star. You should modify your implementation of
ChatServer so that it creates two
ServerSocket objects, one which clients connect to in precisely the same way as they did in Workbook 5, and one which other Java chat servers can connect to in order to share serialised copies of all the
Message objects which are passed through their own instance of
MultiQueue. As a result, your program must accept two port numbers on the command line, the first represents the client port and the second represents the federation port which is used by other servers. In order to specify how a set of servers should be connected together when your server starts, it should accept a list of zero or more other servers which it should connect to as arguments on the command line. Consequently if the user provides less than two arguments, your program should terminate after printing:
Usage: ChatServer <dbpath> <client> <fed> [fedsrv1:port fedsrv2:port ...]
If any of the requested federated servers are not available, your server implementation should ignore the federation request from the user and print
Warning: Cannot connect to 'fedserverX:port'. Ignoring.
If the format of the host or port number is wrong, your implementation should ignore the entry and print a warning; for example if the user enters
example.com:twenty, your program should output
Warning: cannot interpret 'example.com:twenty' as 'fedsrv:port'. Ignoring.
You may change the implementation of your server as you see fit to support this new functionality, but you must not change your implementation of the Java chat client. In other words, your implementation should continue to work with the code you wrote for Ticklet 2.
Once you believe you have completed this exercise, you should generate two jar files to support testing. One, called
chatclient.jar, should contain the code for Ticklet 2 with the manifest file specifying the main class
uk.ac.cam.crsid.fjava.tick2.ChatClient. The other, called,
chatserver.jar should contain your new implementation of the Java chat server and specify the main class as
Open up two terminal windows and execute the following commands, one in each terminal window:
java -jar chatserver.jar /home/crsid/db1 1234 5678 java -jar chatserver.jar /home/crsid/db2 2222 1111 localhost:5678
Then start up a further two terminal windows and execute the following commands, one in each terminal:
java -jar chatclient.jar localhost 1234 java -jar chatclient.jar localhost 2222
Your new implementation of the Java chat server should mean that the two clients you started above can talk with one another as if they were connected to the same Java chat server.
You might find it helpful to construct a class called
FederatedHandler which operates in a similar way to
ClientHandler but can be used to handle both incoming requests for federation from remote servers, as well as make federation requests to other servers.
Beware of message loops: if two servers A and B are connected, a message written by a client to server A should be copied to server B, but this same message should not be repeatedly sent between servers A and B! (You may keep a cache of all messages seen in the last two minutes in order to ignore or reject duplicates. You will need to think carefully about how to construct this cache so that you can detect duplicate messages which might have come from different sources;
java.util.LinkedHashMap might be of some use. If you use this approach, you must reject all messages which are more than two minutes old!)
You may find it helpful to test your server in collaboration with another student. If you do so you should disable the invocation of any method in any new code sent over the socket which contains the
@Execute annotation in your implementation of the Java chat client so that you are not vulnerable to remote code execution exploits.
Please put the source code and byte code of the package
uk.ac.cam.crsid.tick5star and (your possibly modified version of)
uk.ac.cam.cl.fjava.messages into a jar file called
crsid-tick5star.jar. Please email the jar file to
email@example.com. You should receive a response via email within an hour. If you do not, please send an email to