In this exercise you will implement a simulation of a tram tracking system. You will produce a server component to track locations of trams and a client component that simulate trams.
The system consists of one server.
1. Tracking Service – Tracks locations of trams. This server is a singleton.
Tracking Service
The tram stops in each route are hard coded on the server. 1=1,2,3,4,5
96=23,24,2,34,22
101=123,11,22,34,5,4,7
109=88,87,85,80,9,7,2,1
112=110,123,11,22,34,33,29,4
Route 1 consists of trams stops 1, 2, 3, 4 and 5, and route 96 consists of stops 23, 24, 2, 34 and 22.
This service exposes two functions
I. retrieveNextStop() – Accepts a route id, the current tram stop number, which
is the last stop visited by the tram and the previous tram stop number. Returns the next stop in the route. If the current tram stop number is the last one, the next will be the previous one. This simulates the fact that a tram travels up and down a particular route. Only tram clients are allowed to access retrieveNextStop(). The server should use the current stop and the previous stop to identify the direction in which the tram is travelling.
II. updateTramLocation() – Accepts a tram id, route id and stop id, and updates the location details. Only tram clients are allowed to access updateTramLocation().
Tram Clients
These clients are used to simulate actual trams. Tram clients continuously update the tracking service regarding their locations. Between each update request, each tram client sleeps for a time interval that randomly varies between 10 to 20 seconds. This simulates the time taken by a tram to travel from one stop to another.
Updating the location of a tram – Consists of two operations.
1. A tram client retrieves the next stop from the tracking service.
2. Then, it updates the next stop as the current location of the tram. A request is
sent to the tracking service to perform this. The next stop and the current time should be printed on the client console before sending an update request to the tracking service.
Message structure definitions
b) Java definition
public class RPCMessage implements Serializable{ public static final short REQUEST = 0;
public static final short REPLY = 1;
public enum MessageType{REQUEST, REPLY}; private MessageType messageType;
private long TransactionId private long RPCId; private long RequestId; private short procedureId; private String csv_data private short status;
}
Format of csv_data
/* transaction id */
/* Globally unique identifier */
/* Client request message counter */ /* e.g.(1,2,3,4) */
/* data as comma separated values*/
1. Requests sent from a tram client to the tracking server to invoke retrieveNextStop().
route id,current stop number,previous stop number
2. Response from the route server to a tram client when retrieveNextStop() is
invoked.
next stop number
If the next stop number cannot be retrieved (i.e. parameters route id, current stop number and previous stop number are invalid) -1 should be set to the next stop number.
3. Request from a tram client to the tracking server to invoke updateTramLocation(). route id,tram id, stop id
4. Response from the tracking server to a tram client when updateTramLocation() is invoked.
csv_data is empty
Validations
Both clients and servers should make use of the messageType field to test that requests and replies are not confused (i.e. validations should be performed at both clients and servers).
Each transaction should have a unique TransactionId; and servers should copy the TransactionId from the request to the reply so that it can be validate by the client.
Each client should generate a new RPCId for each call; and servers should copy the RPCId from a request to the relevant reply. Clients should validate the RPCId in each reply. RPCId is a globally unique identifier, i.e. no two messages in the system should have the same RPCId, even if different hosts generate them.
Each client should also generate a new RequestId for each request; and the server should copy the RequestId from a request to the relevant reply. Clients should validate the RequestId in each reply. RequestId is used to keep track of the number of requests issued by a client, and each RequestId is unique within the issuing client.
ProcedureId is used to ensure that the request is handled by the appropriate remote method. This field should be validated; a) at both server procedures before commencement of any processing, and b) at clients before processing any replies.
The status parameter is used to indicate the status of a transaction. 0 indicates that the transaction was completed successfully. A non-zero value indicates that there was an error at a server, and clients should display suitable error messages.
System Properties and Limits
1. Each route will have an upper limit of 5 trams.
2. The stops in a route should be hard coded as specified above 3. Each trams stop should have a unique id.
4. Each tram should have a unique id.
2. JAVA SPECIFICATION
Make a copy of your implementation so far. This exercise requires you to write your own marshalling and unmarshalling procedures, which will work on top of the marshalling (Serialization) procedures provided by Java RMI. That is, your server and client functions must be modified to pass objects of type Message over RMI.
import java.io.Serializable;
public class Message implements Serializable{
protected byte data[] = null;
protected int length = 0;
public void marshal(RPCMessage rpcMessage){ }
public RPCMessage unMarshal(){
}
}
When marshalling and un-marshalling data, the following table should be referred to determine the data. The length field should be used to validate marshalled messages.
Type
Explanation
int
A 32-bit (4-byte) integer value
short
A 16-bit (2-byte) integer value
long
A 64-bit (8-byte) integer value
byte
An 8-bit (1-byte) integer value
float
A 32-bit (4-byte) floating-point value
double
A 64-bit (8-byte) floating-point value
char
A 16-bit character using the Unicode encoding scheme
boolean
A true or false value
What to demonstrate
In your submission include a sample run with the following output: the result sent back to the client by the server that performs operations for several clients, and which behaves sensibly when dealing with exceptional conditions. No concurrency control needs to be implemented, so users can interfere with each other’s operations in a way that leads to error conditions, as allowed by the Unix file system.
The record of a session should include date and time.