private static int wsrepl(string filename) { var ws = new Grace.Execution.WebSocketServer(); var wss = ws.Start(); var ls = new LocalScope("repl-inner"); var obj = new UserObject(); var interp = REPL.CreateInterpreter(obj, ls, new WSOutputSink(wss)); interp.LoadPrelude(); var dir = Path.GetFullPath("."); interp.AddModuleRoot(dir); ErrorReporting.SilenceError("P1001"); var memo = interp.Memorise(); string accum = String.Empty; bool unfinished; GraceObject result; wss.JsonReceived += (o, e) => { var je = (JsonWSEvent)e; var root = je.Root; var cn = root.XPathSelectElement("//code"); if (cn == null) { return; } var line = cn.Value; //var line = ((TextWSEvent)e).Text; Console.WriteLine("got text: " + line); accum += line.Replace("\u0000", "") + "\n"; var r = REPL.RunLine( interp, obj, memo, accum, out unfinished, out result); if (result != null) { ls["LAST"] = result; } if (unfinished) { // "Unexpected end of file" is expected here // for unfinished statements. unfinished = false; } else if (r != 0) { // All other errors are errors, and should // clear the accumulated buffer and let the // user start again. accum = String.Empty; } else { accum = String.Empty; } }; wss.Run(); return(0); }
/// <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(); } }