- getMsgs and getLog now both long pull. Much faster and more effecient
- New server class as a subthread of the applet - The applet can now draw itself, and shows port and online status
This commit is contained in:
		
							parent
							
								
									5ce2a651ef
								
							
						
					
					
						commit
						aa6681c03f
					
				|  | @ -72,8 +72,7 @@ class ConnHandler implements Runnable { | |||
| 				//InetAddress addr = new InetSocketAddress("127.0.0.1"); | ||||
| 				if (!client.isConnected())  | ||||
| 					res.error("failed to connect!!!!!!!"); | ||||
| 				//"127.0.0.1", 2600); //dest, res.PORT); | ||||
| 				//client.connect(addr, 2600); | ||||
| 				 | ||||
| 				out = new PrintWriter(client.getOutputStream(), true); | ||||
| 				in = new BufferedReader(new InputStreamReader(client.getInputStream())); | ||||
| 			} catch (Exception e) { | ||||
|  | @ -92,13 +91,14 @@ class ConnHandler implements Runnable { | |||
| 				"Keep-Alive: 300\r\n" +  | ||||
| 				"Connection: keep-alive\r\n" + | ||||
| 				"Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" +  | ||||
| 				"Referer: http://localhost:2600/client.html\r\n" + | ||||
| 				"Referer: " + getIPAddress() + ":" + Integer.toString(res.PORT) + "/client.html\r\n" + | ||||
| 				"Content-Length: " + (all.length()+2) + "\r\n" + | ||||
| 				"Pragma: no-cache\r\n" +  | ||||
| 				"Cache-Control: no-cache\r\n" +  | ||||
| 					"\r\n"); | ||||
| 			out.print(all + "\n\n"); | ||||
| 			out.flush(); | ||||
| 			//res.alert("SENT: " + all); | ||||
| 			//res.log("sent message"); | ||||
| 			//out.close(); | ||||
| 				 | ||||
|  | @ -110,10 +110,12 @@ class ConnHandler implements Runnable { | |||
| 			// read http header | ||||
| 			//res.log("Reading resp header"); | ||||
| 			try { | ||||
| 				String header = in.readLine(); | ||||
| 				while (header.length() >= 3) { | ||||
| 					//res.log("header: " + header); | ||||
| 					header = in.readLine(); | ||||
| 				if (in.ready()) { | ||||
| 					String header = in.readLine(); | ||||
| 					if (header.length() >= 3) { | ||||
| 						//res.log("header: " + header); | ||||
| 						header = in.readLine(); | ||||
| 					} | ||||
| 				} | ||||
| 			} catch (Exception e) { | ||||
| 				res.error("Exception in ajaxCall (reading HTTP response header): " + e.toString()); | ||||
|  | @ -223,7 +225,14 @@ class ConnHandler implements Runnable { | |||
| 			} else if (cmd.equals("greet")) { | ||||
| 				response = getIPAddress() + ":" + res.PORT + " " + res.getNodeData("originURL") ; | ||||
| 			} else if (cmd.equals("getLog")) { | ||||
| 				res.debug("getLog"); | ||||
| 				ArrayList<String> l = res.getLog(); | ||||
| 				if (l.size() == 0) { | ||||
| 					res.debug("logWait"); | ||||
| 					res.logWait(); | ||||
| 					l = res.getLog(); | ||||
| 				} | ||||
| 				res.debug("process Log"); | ||||
| 				response = ""; | ||||
| 				for (int i = l.size()-1; i >= 0; i--) { | ||||
| 					response +=  l.get(i) + "\n"; | ||||
|  | @ -237,7 +246,14 @@ class ConnHandler implements Runnable { | |||
| 				res.queueMsg(req.get("req"));	 | ||||
| 				response = "received on " + res.PORT; | ||||
| 			} else if (cmd.equals("getMsgs")) { | ||||
| 				res.debug("getMsgs"); | ||||
| 				ArrayList<String> mq = res.getMsgs(); | ||||
| 				if (mq.size() == 0) { | ||||
| 					res.debug("mqWait"); | ||||
| 					res.mqWait(); | ||||
| 					mq = res.getMsgs(); | ||||
| 				} | ||||
| 				res.debug("mq process"); | ||||
| 				for(int i =0; i < mq.size(); i++) { | ||||
| 					response += mq.get(i) + "\n\n"; | ||||
| 				} | ||||
|  |  | |||
							
								
								
									
										97
									
								
								Cortex.java
								
								
								
								
							
							
						
						
									
										97
									
								
								Cortex.java
								
								
								
								
							|  | @ -1,5 +1,5 @@ | |||
| import java.applet.*; | ||||
| //import java.awt.*; | ||||
| import java.awt.*; | ||||
| import java.awt.event.*; | ||||
| import javax.swing.Timer; | ||||
| import java.awt.image.*; | ||||
|  | @ -18,71 +18,58 @@ import javax.swing.JOptionPane.*; | |||
| 
 | ||||
| 
 | ||||
| public class Cortex extends Applet { | ||||
| 	//private final int PORT = 2600; // in ResManager now | ||||
| 	private ServerSocket server; | ||||
| 
 | ||||
| 	private Server server;	 | ||||
| 	private ResManager res = new ResManager(this); | ||||
| 	 | ||||
| 	private ResManager res = new ResManager(); | ||||
| 	public void update(Graphics g) | ||||
|         { | ||||
|                 paint(g); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| 	public void paint(Graphics g) { | ||||
| 		Dimension size = getSize(); | ||||
| 		g.setColor(Color.black); | ||||
| 		g.fillRect(0, 0, (int) size.getWidth(), (int) size.getHeight()); | ||||
| 		 | ||||
| 		g.setColor(new Color(223, 200, 255)); | ||||
| 		g.drawString("Cortex Server",8,12); | ||||
| 		 | ||||
| 		if(!res.killSwitch) { | ||||
| 			g.setColor(new Color(40, 255, 80)); | ||||
| 			g.drawString("Online on port",2, 28); | ||||
| 			g.drawString(Integer.toString(res.PORT), 35, 42); | ||||
| 			/*if (res.mqSize() > 0) { | ||||
| 				g.setColor(Color.green); | ||||
| 				g.drawString(".", 80, 42); | ||||
| 			} else { | ||||
| 				g.setColor(Color.red); | ||||
| 				g.drawString(".", 80, 42); | ||||
| 			}*/ | ||||
| 		} else { | ||||
| 			g.setColor(Color.red); | ||||
| 			g.drawString("Offline", 25,28); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 	 | ||||
| 	/*URL getCodeBase() throws Exception { | ||||
| 			return new URL("file:///home/dan/src/school/cpsc416/cortex/"); | ||||
| 	}*/ | ||||
| 	 | ||||
| 	/* main | ||||
| 	 * Main HTTP server.  Accepts connections on PORT and passes them to threads  | ||||
| 	 *   in the form of ConnHandlers to deal with | ||||
| 	 */ | ||||
| 	public void init() { | ||||
| 		//javax.swing.JOptionPane.showMessageDialog(null, "APPLET STARTING!!!!"); | ||||
| 		//res.alert("Starting..."); | ||||
| 		res.putNodeData("originURL", getCodeBase().toString()); | ||||
| 		res.reloadSite(); | ||||
| 		//server =  | ||||
| 		new Thread(new Server(res, getCodeBase().toString(), this)).start();	 | ||||
| 		 | ||||
| 		//res.alert("Loaded site"); | ||||
| 		 | ||||
| 		boolean bound = false; | ||||
| 		while(!bound) | ||||
| 		{ | ||||
| 			try { | ||||
| 				server = new ServerSocket(res.PORT); | ||||
| 				bound = true; | ||||
| 			} catch (IOException e) { | ||||
| 				res.PORT++; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		/* | ||||
| 		// be reasonably sure we've secured a valid port | ||||
| 		try { | ||||
| 			server = new ServerSocket(res.PORT);	 | ||||
| 		} catch (IOException e) { | ||||
| 			res.error( "It appears another Cortex Node is already running on this computer, making this one superfulous.\nShutting down...");  | ||||
| 		}*/ | ||||
| 			Thread.sleep(100); | ||||
| 		} catch (Exception e) { /* meh */ } | ||||
| 		repaint(); | ||||
| 		 | ||||
| 		/*try { | ||||
| 			JSObject win = JSObject.getWindow(this); | ||||
| 			win.eval("load();"); | ||||
| 		} catch(Exception e) { | ||||
| 			res.error(e.toString()); | ||||
| 		}*/ | ||||
| 		 | ||||
| 		try { | ||||
| 			//res.alert("running server"); | ||||
| 			while (!res.killSwitch) {		 | ||||
| 				Socket sock = server.accept(); | ||||
| 				//res.alert("ACCEPTED!"); | ||||
| 				 | ||||
| 				new Thread(new ConnHandler(sock, res)).start();		 | ||||
| 				 | ||||
| 				//handler.run(); | ||||
| 				//res.alert("RESTARTING LOOP"); | ||||
| 			} | ||||
| 			server.close(); | ||||
| 		} catch (IOException e) { | ||||
| 			System.out.println("IOException in init(): " + e.toString()); | ||||
| 			res.error( "IOException in init(): " + e.toString()); | ||||
| 		} | ||||
| 		// HANDLE QUIT? | ||||
| 
 | ||||
| 		//res.error("QUITING!"); | ||||
|  	} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										5
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										5
									
								
								Makefile
								
								
								
								
							|  | @ -1,5 +1,5 @@ | |||
| Cortex.jar: Cortex.class ConnHandler.class ResManager.class | ||||
| 	jar cvf Cortex.jar Cortex.class ConnHandler.class ResManager.class | ||||
| 	jar cvf Cortex.jar Cortex.class Server.class ConnHandler.class ResManager.class | ||||
| 	jarsigner Cortex.jar cortex_cert  | ||||
| 
 | ||||
| ResManager.class: ResManager.java | ||||
|  | @ -8,6 +8,9 @@ ResManager.class: ResManager.java | |||
| ConnHandler.class: ConnHandler.java | ||||
| 	javac ConnHandler.java | ||||
| 
 | ||||
| Server.class: Server.java | ||||
| 	javac Server.java | ||||
| 
 | ||||
| Cortex.class: Cortex.java | ||||
| 	javac Cortex.java | ||||
| 	 | ||||
|  |  | |||
							
								
								
									
										142
									
								
								ResManager.java
								
								
								
								
							
							
						
						
									
										142
									
								
								ResManager.java
								
								
								
								
							|  | @ -1,3 +1,4 @@ | |||
| import java.applet.*; | ||||
| import java.util.HashMap; | ||||
| import javax.swing.JOptionPane.*; | ||||
| import java.util.ArrayList; | ||||
|  | @ -11,20 +12,27 @@ import java.net.*; | |||
| 
 | ||||
| class ResManager { | ||||
| 	public /*final*/ int PORT = 2600; | ||||
| 	private Applet applet; | ||||
| 	 | ||||
| 	FileWriter debugFW = null; | ||||
| 	BufferedWriter debugOut = null; | ||||
| 
 | ||||
| 	private HashMap<String, byte[]> site = new HashMap<String, byte[]>(); | ||||
| 	private HashMap<String, String> nodeData = new HashMap<String, String>(); | ||||
| 	 | ||||
| 	// Internal Activity Log | ||||
| 	private ArrayList<String> log = new ArrayList<String>(); | ||||
| 	private boolean logLock = false; | ||||
| 	//private boolean logLock = false; | ||||
| 	private DateFormat logDateFormat = new SimpleDateFormat("HH:mm:ss"); | ||||
| 	 | ||||
| 	private boolean mqLock = false; | ||||
| 	// Message Queue | ||||
| 	//private boolean mqLock = false; | ||||
| 	private ArrayList<String> msgQueue = new ArrayList<String>(); | ||||
| 
 | ||||
| 	public boolean killSwitch = false;	 | ||||
| 	 | ||||
| 	public ResManager() { | ||||
| 	public ResManager(Applet a) { | ||||
| 		applet = a; | ||||
| 	} | ||||
| 	 | ||||
| 	public void putSite(String key, byte[] val) { | ||||
|  | @ -43,62 +51,74 @@ class ResManager { | |||
| 		return nodeData.get(key); | ||||
| 	} | ||||
| 	 | ||||
| 	private synchronized void logLock() { | ||||
| 		while (logLock == true) { | ||||
| 	public void log(String l) { | ||||
| 		synchronized (log) { | ||||
| 			Date d = new Date(); | ||||
| 			log.add(logDateFormat.format(d) + ": " + l); | ||||
| 			log.notifyAll(); | ||||
| 			if (debugOut != null) { | ||||
| 			try { | ||||
| 				wait(); | ||||
| 			} catch (Exception e) { | ||||
| 				error("logLock: " + e.toString()); | ||||
| 					debugOut.write(logDateFormat.format(d) + ": " + l + "\n"); | ||||
| 					debugOut.flush(); | ||||
| 				} catch (IOException e) { | ||||
| 					// Fail | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		logLock = true; | ||||
| 		//javax.swing.JOptionPane.showMessageDialog(null, " Locked"); | ||||
| 	} | ||||
| 	 | ||||
| 	private synchronized void logUnlock() { | ||||
| 		logLock = false; | ||||
| 		//javax.swing.JOptionPane.showMessageDialog(null, " UnLocked"); | ||||
| 	} | ||||
| 	 | ||||
| 	public synchronized void log(String l) { | ||||
| 		logLock(); | ||||
| 		Date d = new Date(); | ||||
| 		log.add(logDateFormat.format(d) + ": " + l); | ||||
| 		logUnlock(); | ||||
| 	} | ||||
| 	 | ||||
| 	private synchronized void mqLock() { | ||||
| 		while(mqLock == true) { | ||||
| 			try {  | ||||
| 				wait(); | ||||
| 			} catch (Exception e) { | ||||
| 				error("mqLock: " + e.toString()); | ||||
| 	public void debug(String l) { | ||||
| 		synchronized (log) { | ||||
| 			Date d = new Date(); | ||||
| 			try { | ||||
| 				debugOut.write(logDateFormat.format(d) + ": " + l + "\n"); | ||||
| 				debugOut.flush(); | ||||
| 			} catch (IOException e) { | ||||
| 				// Fail | ||||
| 			} | ||||
| 		} | ||||
| 		mqLock = true; | ||||
| 	} | ||||
| 	 | ||||
| 	private synchronized void mqUnlock() { | ||||
| 		mqLock = false; | ||||
| 	public void logWait() { | ||||
| 		synchronized(log) { | ||||
| 			try { | ||||
| 				log.wait(); | ||||
| 			} catch (Exception e) { } | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public synchronized void queueMsg(String m) { | ||||
| 		mqLock(); | ||||
| 		msgQueue.add(m); | ||||
| 		mqUnlock(); | ||||
| 	public void queueMsg(String m) { | ||||
| 		synchronized (msgQueue) { | ||||
| 			msgQueue.add(m); | ||||
| 			msgQueue.notifyAll(); | ||||
| 		} | ||||
| 		//applet.repaint(); | ||||
| 	} | ||||
| 	 | ||||
| 	public synchronized ArrayList<String> getMsgs() { | ||||
| 		mqLock(); | ||||
| 		ArrayList<String> mq = msgQueue; | ||||
| 		msgQueue = new ArrayList<String>(); | ||||
| 		mqUnlock(); | ||||
| 	public void mqWait() { | ||||
| 		synchronized(msgQueue) { | ||||
| 			try { | ||||
| 				msgQueue.wait(); | ||||
| 			} catch (Exception e) { } | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public ArrayList<String> getMsgs() { | ||||
| 		ArrayList<String> mq; | ||||
| 		synchronized(msgQueue) { | ||||
| 			mq = msgQueue; | ||||
| 			msgQueue = new ArrayList<String>(); | ||||
| 		} | ||||
| 		//applet.repaint(); | ||||
| 		return mq; | ||||
| 	} | ||||
| 	 | ||||
| 	public int mqSize() { | ||||
| 		return msgQueue.size(); | ||||
| 	} | ||||
| 	 | ||||
| 	public void alert(String a) { | ||||
| 		javax.swing.JOptionPane.showMessageDialog(null, a); | ||||
| 		javax.swing.JOptionPane.showMessageDialog(null, Integer.toString(PORT)  + ": " + a); | ||||
| 		log("ALERT> " + a); | ||||
| 	} | ||||
| 	 | ||||
|  | @ -108,13 +128,13 @@ class ResManager { | |||
| 	} | ||||
| 	 | ||||
| 	// returns the current log and RESETS it | ||||
| 	public synchronized ArrayList<String> getLog()  | ||||
| 	public ArrayList<String> getLog()  | ||||
| 	{ | ||||
| 		logLock(); | ||||
| 		ArrayList<String> tmp = log; | ||||
| 		log = new ArrayList<String>(); | ||||
| 		logUnlock(); | ||||
| 		return tmp; | ||||
| 		synchronized(log) { | ||||
| 			ArrayList<String> tmp = log; | ||||
| 			log = new ArrayList<String>(); | ||||
| 			return tmp; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void reloadSite() { | ||||
|  | @ -158,22 +178,18 @@ class ResManager { | |||
| 		} | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| 	/* | ||||
| 	public synchronized void put(String key, String val) { | ||||
| 		//javax.swing.JOptionPane.showMessageDialog(null, "putting: '" + key + "'"); | ||||
| 		//javax.swing.JOptionPane.showMessageDialog(null, val); | ||||
| 		//data.put(key, val); | ||||
| 	} | ||||
| 	 | ||||
| 	public synchronized String get(String key) { | ||||
| 		//javax.swing.JOptionPane.showMessageDialog(null, "getting: '" + key + "'"); | ||||
| 		//javax.swing.JOptionPane.showMessageDialog(null, "from: " + data.keySet().toString()); | ||||
| 		 | ||||
| 		//return data.get(key); | ||||
| 	}*/ | ||||
| 
 | ||||
| 
 | ||||
| 	public void openDebugLog(String ip) { | ||||
| 		String fname = "cortex." + ip + ":" + Integer.toString(PORT) + ".log"; | ||||
| 		//FileWriter debugFileW = new FileWriter("/tmp/" + fname); | ||||
| 		try { | ||||
| 			debugFW = new FileWriter("/tmp/" + fname); | ||||
| 	        	debugOut = new BufferedWriter(debugFW); | ||||
| 	        } catch (IOException e) { | ||||
| 	        	debugFW = null; | ||||
| 	        	debugOut = null; | ||||
| 	        	error("Failed to open debug log"); | ||||
| 	        } | ||||
| 	}	 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
							
								
								
									
										16
									
								
								client.html
								
								
								
								
							
							
						
						
									
										16
									
								
								client.html
								
								
								
								
							|  | @ -131,6 +131,9 @@ function getLog() { | |||
| 			var log = document.getElementById('log'); | ||||
| 			//alert("getLog() resp: " + resp); | ||||
| 			log.value =  resp + log.value; | ||||
| 			// Since getLog returns (a call back is called later) | ||||
| 			// this is tail recursive friendly | ||||
| 			getLog(); | ||||
| 		}); | ||||
| 	ajaxSend(http, "cmd=getLog\n\n", retfn); | ||||
| } | ||||
|  | @ -170,7 +173,11 @@ function getMsgs() { | |||
| 	var retfn = returnfn(http,  | ||||
| 		function(resp) { | ||||
| 			//log("getMsgs: len > 0"); | ||||
| 			log("getMsgs: " + resp); | ||||
| 			queueMsgs(resp); | ||||
| 			// Since getMsgs returns (a call back is called later) | ||||
| 			// this is tail recursive friendly | ||||
| 			getMsgs();  | ||||
| 		}); | ||||
| 	ajaxSend(http, "cmd=getMsgs\n\n", retfn); | ||||
| } | ||||
|  | @ -801,14 +808,14 @@ function cron() { | |||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	if (runCount % 5 == 0) { | ||||
| 	/*if (runCount % 5 == 0) { | ||||
| 		getMsgs(); | ||||
| 	} | ||||
| 	}*/ | ||||
| 	 | ||||
| 	// once a second | ||||
| 	if (runCount % 10 == 0) { | ||||
| 		ping(); | ||||
| 		getLog(); | ||||
| 		//getLog(); | ||||
| 		setStatus(); | ||||
| 		checkLocks(); | ||||
| 		updateTestsStatus(); | ||||
|  | @ -1845,6 +1852,9 @@ function updateFinalResults() { | |||
| 	 | ||||
| 
 | ||||
| var cronID = setInterval("cron()", 100); | ||||
| getMsgs(); | ||||
| getLog(); | ||||
| 
 | ||||
| 
 | ||||
| function page(p) { | ||||
| 	// turn off all pages | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ | |||
| 		<input type="button" value="Load" onClick="load()" /> | ||||
| 		<input id="port" size="4" value="2600" /> | ||||
| 
 | ||||
| 	<applet code="Cortex.class" archive="Cortex.jar" width="50" height="50" id="cortex"></applet> | ||||
| 	<applet code="Cortex.class" archive="Cortex.jar" width="100" height="50" id="cortex"></applet> | ||||
| 	<b>Coretex Client</b><br/> | ||||
| 
 | ||||
| 	<iframe height="400" width="600" id="client" name="client"> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue