class Server implements ServerExports {
int index = -1;
public int register(ClientExports client) {
clients[++index] = client;
return index;
}
ClientExports clients[] = new ClientExports[100];
public void broadcast(Update event) {
}
}
public interface ServerExports {
public int register(ClientExports client);
public void broadcast(Update event);
}
2. This describes the kind of updates that will be sent:
class Update {
}
3. We can start describing the clients now:
class Client extends Thread {
public void update(Update event) {
}
public void run() {
}
}
public interface ClientExports {
public void update(Update event);
}
4. Can we put all these together already?
public class Simulation {
public static void main(String[] args) {
// on the server's host (server starts first)
Server server = new Server();
// on any of the clients' hosts
Client adrian = new Client("Adrian");
Client raja = new Client("Raja");
Client dijkstra = new Client("Edsger");
adrian.start();
raja.start();
dijkstra.start();
}
}
5. Can't we make the clients look a bit more realistic?
class Client extends Thread implements ClientExports {
String name;
public Client(String name) {
this.name = name;
}
public void update(Update event) {}
public void run() {
while (true) {
try {
sleep((int)(Math.random() * 6000 + 1000));
} catch (Exception e) {
}
System.out.println(this.name + " here...");
}
}
}
6. So how does the program run now?
class Simulation {
public static void main(String[] args) {
// on the server's host
Server server = new Server();
// on any of the clients' hosts
ServerExports far = server;
Client adrian = new Client("Adrian");
adrian.id = far.register(adrian);
adrian.server = far;
adrian.start();
Client raja = new Client("Raja");
raja.id = far.register(raja);
raja.server = far;
raja.start();
Client dijkstra = new Client("Edsger");
dijkstra.id = far.register(dijkstra);
dijkstra.server = far;
dijkstra.start();
}
}
7. Most classes have changed:
class Update {
String message;
Update(String message) {
this.message = message;
}
public String toString() {
return message;
}
}
class Client extends Thread implements ClientExports {
String name;
int id;
ServerExports server;
public Client(String name) {
this.name = name;
}
public void update(Update event) {
System.out.println(this.name +
" receives: ***(" + event + ")*** ");
}
public void run() {
while (true) {
try {
sleep((int)(Math.random() * 6000 + 10000));
} catch (Exception e) {
}
server.broadcast(new Update(this.name + " says: Howdy!"));
}
}
}
class Server implements ServerExports {
ClientExports clients[] = new ClientExports[100];
int index = -1;
synchronized public int register(ClientExports client) {
clients[++index] = client;
return index;
}
synchronized public void broadcast(Update event) {
for (int i = 0; i <= index; i++)
clients[i].update(event);
}
}
8. One should try/run the program now. 9. Well, we're done.
10. We can now switch to a networked version.
11. Here's the client:
import java.rmi.*;
import java.rmi.server.*;
public class Client extends Thread implements ClientExports {
String name;
int id;
ServerExports server;
public Client(String name) {
this.name = name;
}
public void update(Update event) throws RemoteException {
System.out.println(this.name + " receives: ***(" + event + ")*** ");
}
public void run() {
while (true) {
try {
sleep((int)(Math.random() * 6000 + 10000));
server.broadcast(
new Update(this.name + " says: Howdy!"));
} catch (Exception e) { }
}
}
public static void main(String[] args) {
}
}
12. Here's the client interface now:
import java.rmi.*;
public interface ClientExports extends Remote {
public void update(Update event) throws RemoteException;
}
13. Here's the server code:
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
public class Server extends UnicastRemoteObject
implements ServerExports {
ClientExports clients[] = new ClientExports[100];
int index = -1;
synchronized public int register(ClientExports client)
throws RemoteException {
clients[++index] = client;
return index;
}
synchronized public void broadcast(Update event)
throws RemoteException {
for (int i = 0; i <= index; i++)
clients[i].update(event);
}
public Server() throws RemoteException {
System.out.println("Server being initialized... ");
}
public static void main(String[] args) {
}
}
14. Here's the current server interface:
import java.rmi.*;
public interface ServerExports extends Remote {
public int register(ClientExports client) throws RemoteException;
public void broadcast(Update event) throws RemoteException;
}
15. Careful with compilation now:
16. Now the finishing touches.frilled.cs.indiana.edu%ls -ld *.java -rw---- 1 dgerman faculty 775 Nov 14 21:55 Client.java -rw---- 1 dgerman faculty 132 Nov 14 21:50 ClientExports.java -rw---- 1 dgerman faculty 635 Nov 14 21:53 Server.java -rw---- 1 dgerman faculty 205 Nov 14 21:51 ServerExports.java -rw---- 1 dgerman faculty 172 Nov 14 21:47 Update.java frilled.cs.indiana.edu%javac *.java frilled.cs.indiana.edu%rmic Server frilled.cs.indiana.edu%rmic Client frilled.cs.indiana.edu%ls -ld *.class -rw---- 1 dgerman faculty 1242 Nov 14 21:58 Client.class -rw---- 1 dgerman faculty 214 Nov 14 21:58 ClientExports.class -rw---- 1 dgerman faculty 1593 Nov 14 21:58 Client_Skel.class -rw---- 1 dgerman faculty 2877 Nov 14 21:58 Client_Stub.class -rw---- 1 dgerman faculty 679 Nov 14 21:58 Server.class -rw---- 1 dgerman faculty 267 Nov 14 21:58 ServerExports.class -rw---- 1 dgerman faculty 1937 Nov 14 21:58 Server_Skel.class -rw---- 1 dgerman faculty 3613 Nov 14 21:58 Server_Stub.class -rw---- 1 dgerman faculty 349 Nov 14 21:58 Update.class frilled.cs.indiana.edu%
17. The server's main becomes:
static void main(String[] args) {
System.setSecurityManager(new RMISecurityManager());
try {
Server pam = new Server();
Registry cat =
LocateRegistry.createRegistry(Integer.parseInt(args[0]));
cat.bind("Dirac", pam);
System.out.println("Server is ready... ");
} catch (Exception e) {
System.out.println("Server error: " + e + "... ");
}
}
18. The client's main becomes:
public static void main(String[] args) {
try {
ServerExports far =
(ServerExports)Naming.lookup(
"rmi://" + args[0] + ":" + args[1] + "/Dirac");
Client here = new Client(args[2]);
UnicastRemoteObject.exportObject(here);
here.id = far.register(here);
here.server = far;
here.start();
} catch (Exception e) {
System.out.println("Error in client... " + e);
e.printStackTrace();
}
}
19. Here's how you start the server:
20. Here's how you start the client:java Server <server-port>
21. This is important:java Client <server-host> <server-port> <client-name>
import java.io.*;
public class Update implements Serializable {
Update(String message) {
this.message = message;
}
String message;
public String toString() {
return message;
}
}
22. And this is important too:
frilled.cs.indiana.edu% ls -ld .java*
-rw---- 1 dgerman faculty 56 Nov 14 22:49 .java.policy
frilled.cs.indiana.edu% cat .java.policy
grant {
permission java.security.AllPermission;
};
frilled.cs.indiana.edu%
End of story.