Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Send a procedure call over the wire.
        /// </summary>
        /// <param name="receiver">
        /// Identifier of remote receiving object.
        /// </param>
        /// <param name="name">
        /// Name of procedure
        /// </param>
        /// <param name="args">
        /// Array of arguments to the call.
        /// </param>
        /// <param name="wait">
        /// True to wait for a result, false to return
        /// done immediately.
        /// </param>
        public GraceObject SendCall(int receiver, string name,
                                    object[] args, bool wait)
        {
            if (hardStop)
            {
                Environment.Exit(0);
            }
            if (stop)
            {
                return(GraceObject.Done);
            }
            int theKey = callKey++;

            var stream     = new MemoryStream(10240);
            var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(
                stream
                );
            var xmlDoc = new XmlDocument();
            var root   = xmlDoc.CreateElement("root");

            root.SetAttribute("type", "object");
            xmlDoc.AppendChild(root);

            var mode = xmlDoc.CreateElement("mode");
            var tn   = xmlDoc.CreateTextNode("call");

            mode.AppendChild(tn);
            root.AppendChild(mode);

            var reply = xmlDoc.CreateElement("noreply");

            reply.SetAttribute("type", "boolean");
            tn = xmlDoc.CreateTextNode(wait ? "false" : "true");
            reply.AppendChild(tn);
            root.AppendChild(reply);

            var rec = xmlDoc.CreateElement("receiver");

            rec.SetAttribute("type", "number");
            tn = xmlDoc.CreateTextNode("" + receiver);
            rec.AppendChild(tn);
            root.AppendChild(rec);

            var key = xmlDoc.CreateElement("key");

            key.SetAttribute("type", "number");
            tn = xmlDoc.CreateTextNode("" + theKey);
            key.AppendChild(tn);
            root.AppendChild(key);

            var nameEl = xmlDoc.CreateElement("name");

            tn = xmlDoc.CreateTextNode("" + name);
            nameEl.AppendChild(tn);
            root.AppendChild(nameEl);

            var arguments = xmlDoc.CreateElement("args");

            arguments.SetAttribute("type", "array");
            foreach (var a in args)
            {
                var item = xmlDoc.CreateElement("item");
                arguments.AppendChild(item);
                if (a is string)
                {
                    tn = xmlDoc.CreateTextNode((string)a);
                    item.AppendChild(tn);
                }
                else if (a is GraceNumber)
                {
                    tn = xmlDoc.CreateTextNode(((GraceNumber)a).Double
                                               .ToString());
                    item.AppendChild(tn);
                    item.SetAttribute("type", "number");
                }
                else if (a is GraceBlock)
                {
                    var b  = (GraceBlock)a;
                    int id = getBlockId(b);
                    item.SetAttribute("type", "object");
                    var obj = xmlDoc.CreateElement("callback");
                    tn = xmlDoc.CreateTextNode("" + id);
                    obj.AppendChild(tn);
                    item.AppendChild(obj);
                }
                else if (a is int[])
                {
                    var id = ((int[])a)[0];
                    item.SetAttribute("type", "object");
                    var obj = xmlDoc.CreateElement("key");
                    tn = xmlDoc.CreateTextNode("" + id);
                    obj.AppendChild(tn);
                    item.AppendChild(obj);
                }
            }
            root.AppendChild(arguments);

#if DEBUG_WS
            Console.WriteLine(xmlDoc.OuterXml);
#endif
            xmlDoc.WriteTo(jsonWriter);
            jsonWriter.Flush();
#if DEBUG_WS
            Console.WriteLine(
                "Capacity = {0}, Length = {1}, Position = {2}\n",
                stream.Capacity.ToString(),
                stream.Length.ToString(),
                stream.Position.ToString());
#endif
            stream.Seek(0, SeekOrigin.Begin);
            var             reader = new StreamReader(stream);
            EventWaitHandle handle;
            if (wait)
            {
                handle = new EventWaitHandle(false,
                                             EventResetMode.ManualReset);
                WebSocketEndpoint.AddEventHandle(theKey, handle);
                wss.Send(reader.ReadToEnd());
                handle.WaitOne();
                return(WebSocketEndpoint.GetEventResult(theKey));
            }
            wss.Send(reader.ReadToEnd());
            return(GraceObject.Done);
        }