// // Othecko 1.1 // // Steve Matuszek // Jack Freelander // University of North Carolina at Chapel Hill // // // MiddleMan.java // Jack Freelander 1.0 // Steve Matuszek 1.1 // // // This class is responsible for passing information back and forth // between children and parents. To be reliable to keeps a list of // other "parents" it can contact in the event that one goes down. // // Since we do not care which parent is contacted, there is no need // to maintain allegiance to any one parent, or re-establish contact // with a parent in the event that it is revived after death. // import java.util.*; import java.io.*; import java.net.*; public class MiddleMan { // These two constants are default values for the location of the applet code and // the location of the output html files. You should definitely change them if you // plan to use these; or you can ignore them if you always pass these values on the // command line. Currently this code requires all the arguments on the command line, // so you would have to change that too. public static final String DEFAULT_CODEBASE = "http://www.cs.unc.edu/~matuszek/othecko/classes/"; public static final String DEFAULT_OUTPUTFILE = "~matuszek/www/othecko/play/middleman.html"; private static final int maxBackLog=100; private int submissionCount = 0; private int maxSubmissions = 0; InetAddress myAddr=null; int myPort = -1; private Vector parents, children, submissions; private ServerSocket serverSocket; private RemoteSystem primaryParent; private MessageObject lastMessage; public MiddleMan(String args[]) { parents = new Vector(); children = new Vector(); submissions = new Vector(); primaryParent = null; lastMessage = null; RemoteSystem rs; // eventually deal with command line arguments as far as genealogy server, etc.. if(args.length < 3) { System.out.println("Usage: java MiddleMan applet-codebase html-file-pathname host1:port1 [host2:port2 [...]] \n\n"); System.exit(0); } // zeroth arg is the location of the applet class (OtheckoApplet.class). // first arg is the html file to output, e.g. "~matuszek/www/othecko/play/middleman5.html". // I recommend having a set location for these and varying middleman{n}.html. // // Thus succeeding args -- 2 and up -- are the hosts to consider parents. Add them as such. for(int i=2;i\n"); html.append("\n"); html.append("\n"); html.append("\n"); html.append("\n"); html.append("No java. "); String out = html.toString(); f.write(out, 0, out.length()); f.flush(); f.close(); System.out.println("Done creating HTML file."); System.out.println(); System.out.println("Ready."); System.out.println(); } catch (Exception e) { System.out.println("Couldn't write index" + filename + ". " + e); System.exit(0); } return true; } public boolean sendSubscribeMessage(RemoteSystem rs) { ObjectOutputStream oos; Socket s = rs.giveMeASocket(); if(myAddr==null) { System.out.println("I do not know my own address in sendSubscribeMessage!!\n"); } if(myPort < 1024) { System.out.println("I do not know my own port # in sendSubscribeMessage!!\n"); } MessageObject message = new MessageObject( null, MessageObject.SUBSCRIBE, new RemoteSystem(myAddr,myPort)); try { oos = new ObjectOutputStream(s.getOutputStream()); //System.out.println("At stage #201\n"); oos.writeObject(message); //System.out.println("At stage #202\n"); oos.flush(); //System.out.println("At stage #203\n"); oos.reset(); //System.out.println("At stage #204\n"); oos.close(); //System.out.println("At stage #205\n"); s.close(); //System.out.println("At stage #206\n"); } catch(Exception e) { System.out.println("Problem, unable to send message to my parent in sendSubscribeMessage\n"); return false; } return true; } public boolean sendEmergencySubscribeMessage(RemoteSystem rs) { ObjectOutputStream oos; Socket s = rs.giveMeASocket(); if(myAddr==null) { System.out.println("I do not know my own address in sendEmergencySubscribeMessage!!\n"); } if(myPort < 1024) { System.out.println("I do not know my own port # in sendEmergencySubscribeMessage!!\n"); } MessageObject message = new MessageObject( null, MessageObject.EMERGENCY_SUBSCRIBE, new RemoteSystem(myAddr,myPort)); try { oos = new ObjectOutputStream(s.getOutputStream()); //System.out.println("At stage #201a\n"); oos.writeObject(message); //System.out.println("At stage #202a\n"); oos.flush(); //System.out.println("At stage #203a\n"); oos.reset(); //System.out.println("At stage #204a\n"); oos.close(); //System.out.println("At stage #205a\n"); s.close(); //System.out.println("At stage #206a\n"); } catch(Exception e) { System.out.println("Problem, unable to send message to my parent in sendEmergencySubscribeMessage\n"); return false; } return true; } public boolean isTimeToSend() { if (submissions == null) { return false; } return (submissions.size() >= maxSubmissions || submissionCount >= maxSubmissions); } public int getMaxSubmissions() { return maxSubmissions; } public void setMaxSubmissions(int i) { maxSubmissions=i; } public boolean addSubmission(Vote v) { System.out.println("Got to add submission\n\n"); System.out.println(v); if(submissions == null || v==null) { return false; } for(int i=0;i0) { System.out.println("Going to subscribe to my primary parent!\n"); sendSubscribeMessage((RemoteSystem)parents.elementAt(0)); primaryParent=(RemoteSystem)parents.elementAt(0); parents.removeElementAt(0); } // Loop waiting for and handling connections while(true) { System.out.println("[-- Waiting for a connection --]\n"); try { sock = serverSocket.accept(); System.out.println("## At point 000\n"); } catch(Exception e) { e.printStackTrace(); System.out.println("Error in accept in server() subroutine\n"); continue; } //System.out.println("## At point 001\n"); System.out.println("[-- Received a connection --]\n"); try { //System.out.println("## At point 001b\n"); InputStream is = sock.getInputStream(); //System.out.println("## At point 001c\n"); ois = new ObjectInputStream(is); //System.out.println("## At point 002\n"); } catch(Exception e) { e.printStackTrace(); System.out.println("Failed to create an object input stream for inbound connection!!\n"); continue; } //System.out.println("## At point 003\n"); try { message = (MessageObject) ois.readObject(); ois.close(); sock.close(); } catch(Exception e) { e.printStackTrace(); System.out.println("Failed to receive a MessageObject in server subroutine\n"); System.exit(0); } if (message==null) { continue; } System.out.println("## At point 004 -- " + message.getType()); switch(message.getType()) { case MessageObject.VOTE: addSubmission((Vote)message.getObject()); break; case MessageObject.VOTE_COLLECTION: addSubmissions((Vector)message.getObject()); break; case MessageObject.SUGGEST_PARENT: suggestParent((RemoteSystem)message.getObject()); break; case MessageObject.GAME_STATE: propagateGameState((MessageObject)message); break; case MessageObject.SUBSCRIBE: subscribe((RemoteSystem)message.getRemoteSystem()); break; case MessageObject.EMERGENCY_SUBSCRIBE: emergencySubscribe((RemoteSystem)message.getRemoteSystem()); break; case MessageObject.UNSUBSCRIBE: unsubscribe((RemoteSystem)message.getRemoteSystem()); break; case MessageObject.HELLO: printGreeting((String)message.getObject(),message.getRemoteSystem()); break; default: System.out.println("Could not figure out to do with inbound object!\n"); System.out.println(message); break; } } } public static void main(String args[]) { new MiddleMan(args); } }