- 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:
Dan 2010-12-31 09:42:12 -05:00
parent 5ce2a651ef
commit aa6681c03f
6 changed files with 162 additions and 130 deletions

View File

@ -72,8 +72,7 @@ class ConnHandler implements Runnable {
//InetAddress addr = new InetSocketAddress("127.0.0.1"); //InetAddress addr = new InetSocketAddress("127.0.0.1");
if (!client.isConnected()) if (!client.isConnected())
res.error("failed to connect!!!!!!!"); res.error("failed to connect!!!!!!!");
//"127.0.0.1", 2600); //dest, res.PORT);
//client.connect(addr, 2600);
out = new PrintWriter(client.getOutputStream(), true); out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream())); in = new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch (Exception e) { } catch (Exception e) {
@ -92,13 +91,14 @@ class ConnHandler implements Runnable {
"Keep-Alive: 300\r\n" + "Keep-Alive: 300\r\n" +
"Connection: keep-alive\r\n" + "Connection: keep-alive\r\n" +
"Content-Type: application/x-www-form-urlencoded; charset=UTF-8\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" + "Content-Length: " + (all.length()+2) + "\r\n" +
"Pragma: no-cache\r\n" + "Pragma: no-cache\r\n" +
"Cache-Control: no-cache\r\n" + "Cache-Control: no-cache\r\n" +
"\r\n"); "\r\n");
out.print(all + "\n\n"); out.print(all + "\n\n");
out.flush(); out.flush();
//res.alert("SENT: " + all);
//res.log("sent message"); //res.log("sent message");
//out.close(); //out.close();
@ -110,10 +110,12 @@ class ConnHandler implements Runnable {
// read http header // read http header
//res.log("Reading resp header"); //res.log("Reading resp header");
try { try {
String header = in.readLine(); if (in.ready()) {
while (header.length() >= 3) { String header = in.readLine();
//res.log("header: " + header); if (header.length() >= 3) {
header = in.readLine(); //res.log("header: " + header);
header = in.readLine();
}
} }
} catch (Exception e) { } catch (Exception e) {
res.error("Exception in ajaxCall (reading HTTP response header): " + e.toString()); res.error("Exception in ajaxCall (reading HTTP response header): " + e.toString());
@ -223,7 +225,14 @@ class ConnHandler implements Runnable {
} else if (cmd.equals("greet")) { } else if (cmd.equals("greet")) {
response = getIPAddress() + ":" + res.PORT + " " + res.getNodeData("originURL") ; response = getIPAddress() + ":" + res.PORT + " " + res.getNodeData("originURL") ;
} else if (cmd.equals("getLog")) { } else if (cmd.equals("getLog")) {
res.debug("getLog");
ArrayList<String> l = res.getLog(); ArrayList<String> l = res.getLog();
if (l.size() == 0) {
res.debug("logWait");
res.logWait();
l = res.getLog();
}
res.debug("process Log");
response = ""; response = "";
for (int i = l.size()-1; i >= 0; i--) { for (int i = l.size()-1; i >= 0; i--) {
response += l.get(i) + "\n"; response += l.get(i) + "\n";
@ -237,7 +246,14 @@ class ConnHandler implements Runnable {
res.queueMsg(req.get("req")); res.queueMsg(req.get("req"));
response = "received on " + res.PORT; response = "received on " + res.PORT;
} else if (cmd.equals("getMsgs")) { } else if (cmd.equals("getMsgs")) {
res.debug("getMsgs");
ArrayList<String> mq = res.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++) { for(int i =0; i < mq.size(); i++) {
response += mq.get(i) + "\n\n"; response += mq.get(i) + "\n\n";
} }

View File

@ -1,5 +1,5 @@
import java.applet.*; import java.applet.*;
//import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import javax.swing.Timer; import javax.swing.Timer;
import java.awt.image.*; import java.awt.image.*;
@ -18,71 +18,58 @@ import javax.swing.JOptionPane.*;
public class Cortex extends Applet { 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
* Main HTTP server. Accepts connections on PORT and passes them to threads * Main HTTP server. Accepts connections on PORT and passes them to threads
* in the form of ConnHandlers to deal with * in the form of ConnHandlers to deal with
*/ */
public void init() { public void init() {
//javax.swing.JOptionPane.showMessageDialog(null, "APPLET STARTING!!!!"); //server =
//res.alert("Starting..."); new Thread(new Server(res, getCodeBase().toString(), this)).start();
res.putNodeData("originURL", getCodeBase().toString());
res.reloadSite();
//res.alert("Loaded site"); // be reasonably sure we've secured a valid port
boolean bound = false;
while(!bound)
{
try {
server = new ServerSocket(res.PORT);
bound = true;
} catch (IOException e) {
res.PORT++;
}
}
/*
try { try {
server = new ServerSocket(res.PORT); Thread.sleep(100);
} catch (IOException e) { } catch (Exception e) { /* meh */ }
res.error( "It appears another Cortex Node is already running on this computer, making this one superfulous.\nShutting down..."); repaint();
}*/
/*try { // HANDLE QUIT?
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());
}
//res.error("QUITING!");
} }
} }

View File

@ -1,5 +1,5 @@
Cortex.jar: Cortex.class ConnHandler.class ResManager.class 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 jarsigner Cortex.jar cortex_cert
ResManager.class: ResManager.java ResManager.class: ResManager.java
@ -8,6 +8,9 @@ ResManager.class: ResManager.java
ConnHandler.class: ConnHandler.java ConnHandler.class: ConnHandler.java
javac ConnHandler.java javac ConnHandler.java
Server.class: Server.java
javac Server.java
Cortex.class: Cortex.java Cortex.class: Cortex.java
javac Cortex.java javac Cortex.java

View File

@ -1,3 +1,4 @@
import java.applet.*;
import java.util.HashMap; import java.util.HashMap;
import javax.swing.JOptionPane.*; import javax.swing.JOptionPane.*;
import java.util.ArrayList; import java.util.ArrayList;
@ -11,20 +12,27 @@ import java.net.*;
class ResManager { class ResManager {
public /*final*/ int PORT = 2600; 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, byte[]> site = new HashMap<String, byte[]>();
private HashMap<String, String> nodeData = new HashMap<String, String>(); private HashMap<String, String> nodeData = new HashMap<String, String>();
// Internal Activity Log
private ArrayList<String> log = new ArrayList<String>(); private ArrayList<String> log = new ArrayList<String>();
private boolean logLock = false; //private boolean logLock = false;
private DateFormat logDateFormat = new SimpleDateFormat("HH:mm:ss"); 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>(); private ArrayList<String> msgQueue = new ArrayList<String>();
public boolean killSwitch = false; public boolean killSwitch = false;
public ResManager() { public ResManager(Applet a) {
applet = a;
} }
public void putSite(String key, byte[] val) { public void putSite(String key, byte[] val) {
@ -43,62 +51,74 @@ class ResManager {
return nodeData.get(key); return nodeData.get(key);
} }
private synchronized void logLock() { public void log(String l) {
while (logLock == true) { synchronized (log) {
Date d = new Date();
log.add(logDateFormat.format(d) + ": " + l);
log.notifyAll();
if (debugOut != null) {
try { try {
wait(); debugOut.write(logDateFormat.format(d) + ": " + l + "\n");
} catch (Exception e) { debugOut.flush();
error("logLock: " + e.toString()); } catch (IOException e) {
// Fail
}
} }
} }
logLock = true;
//javax.swing.JOptionPane.showMessageDialog(null, " Locked");
} }
private synchronized void logUnlock() { public void debug(String l) {
logLock = false; synchronized (log) {
//javax.swing.JOptionPane.showMessageDialog(null, " UnLocked"); Date d = new Date();
} try {
debugOut.write(logDateFormat.format(d) + ": " + l + "\n");
public synchronized void log(String l) { debugOut.flush();
logLock(); } catch (IOException e) {
Date d = new Date(); // Fail
log.add(logDateFormat.format(d) + ": " + l);
logUnlock();
}
private synchronized void mqLock() {
while(mqLock == true) {
try {
wait();
} catch (Exception e) {
error("mqLock: " + e.toString());
} }
} }
mqLock = true;
} }
private synchronized void mqUnlock() { public void logWait() {
mqLock = false; synchronized(log) {
try {
log.wait();
} catch (Exception e) { }
}
} }
public synchronized void queueMsg(String m) { public void queueMsg(String m) {
mqLock(); synchronized (msgQueue) {
msgQueue.add(m); msgQueue.add(m);
mqUnlock(); msgQueue.notifyAll();
}
//applet.repaint();
} }
public synchronized ArrayList<String> getMsgs() { public void mqWait() {
mqLock(); synchronized(msgQueue) {
ArrayList<String> mq = msgQueue; try {
msgQueue = new ArrayList<String>(); msgQueue.wait();
mqUnlock(); } catch (Exception e) { }
}
}
public ArrayList<String> getMsgs() {
ArrayList<String> mq;
synchronized(msgQueue) {
mq = msgQueue;
msgQueue = new ArrayList<String>();
}
//applet.repaint();
return mq; return mq;
} }
public int mqSize() {
return msgQueue.size();
}
public void alert(String a) { public void alert(String a) {
javax.swing.JOptionPane.showMessageDialog(null, a); javax.swing.JOptionPane.showMessageDialog(null, Integer.toString(PORT) + ": " + a);
log("ALERT> " + a); log("ALERT> " + a);
} }
@ -108,13 +128,13 @@ class ResManager {
} }
// returns the current log and RESETS it // returns the current log and RESETS it
public synchronized ArrayList<String> getLog() public ArrayList<String> getLog()
{ {
logLock(); synchronized(log) {
ArrayList<String> tmp = log; ArrayList<String> tmp = log;
log = new ArrayList<String>(); log = new ArrayList<String>();
logUnlock(); return tmp;
return tmp; }
} }
public void reloadSite() { 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");
}
}
} }

View File

@ -131,6 +131,9 @@ function getLog() {
var log = document.getElementById('log'); var log = document.getElementById('log');
//alert("getLog() resp: " + resp); //alert("getLog() resp: " + resp);
log.value = resp + log.value; 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); ajaxSend(http, "cmd=getLog\n\n", retfn);
} }
@ -170,7 +173,11 @@ function getMsgs() {
var retfn = returnfn(http, var retfn = returnfn(http,
function(resp) { function(resp) {
//log("getMsgs: len > 0"); //log("getMsgs: len > 0");
log("getMsgs: " + resp);
queueMsgs(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); ajaxSend(http, "cmd=getMsgs\n\n", retfn);
} }
@ -801,14 +808,14 @@ function cron() {
} }
if (runCount % 5 == 0) { /*if (runCount % 5 == 0) {
getMsgs(); getMsgs();
} }*/
// once a second // once a second
if (runCount % 10 == 0) { if (runCount % 10 == 0) {
ping(); ping();
getLog(); //getLog();
setStatus(); setStatus();
checkLocks(); checkLocks();
updateTestsStatus(); updateTestsStatus();
@ -1845,6 +1852,9 @@ function updateFinalResults() {
var cronID = setInterval("cron()", 100); var cronID = setInterval("cron()", 100);
getMsgs();
getLog();
function page(p) { function page(p) {
// turn off all pages // turn off all pages

View File

@ -29,7 +29,7 @@
<input type="button" value="Load" onClick="load()" /> <input type="button" value="Load" onClick="load()" />
<input id="port" size="4" value="2600" /> <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/> <b>Coretex Client</b><br/>
<iframe height="400" width="600" id="client" name="client"> <iframe height="400" width="600" id="client" name="client">