2. This describes the kind of updates that will be sent: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); }
3. We can start describing the clients now:class Update { }
4. Can we put all these together already?class Client extends Thread { public void update(Update event) { } public void run() { } } public interface ClientExports { public void update(Update event); }
5. Can't we make the clients look a bit more realistic?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(); } }
6. So how does the program run now?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..."); } } }
7. Most classes have changed: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(); } }
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!")); } } }
8. One should try/run the program now.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); } }
9. Well, we're done.
10. We can now switch to a networked version.
11. Here's the client:
12. Here's the client interface now: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) { } }
13. Here's the server code:import java.rmi.*; public interface ClientExports extends Remote { public void update(Update event) throws RemoteException; }
14. Here's the current server interface: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) { } }
15. Careful with compilation now:import java.rmi.*; public interface ServerExports extends Remote { public int register(ClientExports client) throws RemoteException; public void broadcast(Update event) throws RemoteException; }
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:
18. The client'sstatic 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 + "... "); } }
main
becomes:
19. Here's how you start the server: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(); } }
20. Here's how you start the client:java Server <server-port>
21. This is important:java Client <server-host> <server-port> <client-name>
22. And this is important too:import java.io.*; public class Update implements Serializable { Update(String message) { this.message = message; } String message; public String toString() { return message; } }
End of story.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%