/// <summary> /// Start a web socket server on a different thread, modifying /// the given interpreter to use it. /// </summary> /// <param name="current">Current interpreter</param> public static Thread WSServeThread(Interpreter current) { var ws = new Grace.Execution.WebSocketServer(); var wss = ws.Start(); var runningThread = Thread.CurrentThread; var runningSink = new WSOutputSink(wss); current.RPCSink = runningSink; wss.JsonReceived += (o, e) => { var je = (JsonWSEvent)e; var root = je.Root; var md = root.XPathSelectElement("//mode"); var mode = md.Value; if (mode == "stop") { Console.WriteLine("Program stopped on remote end."); runningSink.Stop(); runningSink.HardStop(); wss.Stop(); WebSocketEndpoint.Stop(); return; } else if (mode == "response") { processResponse(root); return; } else if (mode == "callback") { if (runningThread != null) { processCallback(root, runningSink); } return; } else if (mode == "ack") { return; } else { Console.WriteLine("unknown mode " + mode); } }; var thread = new Thread(() => { wss.Run(); }); thread.Start(); return(thread); }
/// <summary> /// Start a WebSocket server. /// </summary> public static int WSServe() { var ws = new Grace.Execution.WebSocketServer(); var wss = ws.Start(); Thread runningThread = null; WSOutputSink runningSink = null; while (true) { wss.JsonReceived += (o, e) => { var je = (JsonWSEvent)e; var root = je.Root; var md = root.XPathSelectElement("//mode"); var mode = md.Value; if (mode == "stop") { if (runningThread != null) { runningSink.Stop(); runningThread.Abort(); runningThread = null; runningSink = null; } return; } else if (mode == "response") { processResponse(root); return; } else if (mode == "callback") { if (runningThread != null) { processCallback(root, runningSink); } return; } else if (mode == "ack") { return; } else if (mode != "build" && mode != "run") { return; } var cn = root.XPathSelectElement("//code"); var mn = root.XPathSelectElement("//modulename"); var code = cn.Value; var modname = mn.Value; moduleCode[modname] = code; var sink = new WSOutputSink(wss); runningSink = sink; var thread = new Thread(() => { var startSent = wss.SentFrames; var startReceived = wss.ReceivedFrames; var startTime = DateTime.Now; try { runModule(code, modname, mode, sink); log("Module " + modname + " completed " + mode + "."); runningThread = null; summarise(wss, startSent, startReceived, DateTime.Now - startTime); } catch (WebSocketClosedException) { log("Lost WebSocket connection " + "while running module " + modname + "."); runningThread = null; summarise(wss, startSent, startReceived, DateTime.Now - startTime); } catch (ThreadAbortException) { log("Execution of " + modname + " aborted."); Thread.ResetAbort(); summarise(wss, startSent, startReceived, DateTime.Now - startTime); } }); runningThread = thread; log("Spawning thread to " + mode + " " + modname + "..."); thread.Start(); }; wss.Run(); wss = ws.Next(); } }