Esempio n. 1
0
        public bool process(Servers.AsynchronousServer.ClientConnection cc, HTTPRequest request)
        {
            DataSources dataSources = new DataSources();

            if (request.path.StartsWith(PAGE_PREFIX))
            {
                if (request.requestType == HTTPRequest.GET)
                {
                    dataRates.addUpLinkPoint(System.DateTime.Now, request.path.Length * UpLinkDownLinkRate.BITS_PER_BYTE);
                }
                else if (request.requestType == HTTPRequest.POST)
                {
                    dataRates.addUpLinkPoint(System.DateTime.Now, request.content.Length * UpLinkDownLinkRate.BITS_PER_BYTE);
                }

                try
                {
                    dataSources.vessel = kspAPI.getVessel();
                }
                catch (Exception e)
                {
                    PluginLogger.debug(e.Message + " " + e.StackTrace);
                }

                if (request.requestType == HTTPRequest.GET)
                {
                    dataRates.addDownLinkPoint(
                        System.DateTime.Now,
                        ((Servers.MinimalHTTPServer.ClientConnection)cc).Send(new OKResponsePage(
                                                                                  argumentsParse(request.path.Remove(0,
                                                                                                                     request.path.IndexOf(ARGUMENTS_START) + 1),
                                                                                                 dataSources)
                                                                                  )) * UpLinkDownLinkRate.BITS_PER_BYTE);
                }
                else if (request.requestType == HTTPRequest.POST)
                {
                    dataRates.addDownLinkPoint(
                        System.DateTime.Now,
                        ((Servers.MinimalHTTPServer.ClientConnection)cc).Send(new OKResponsePage(
                                                                                  argumentsParse(request.content,
                                                                                                 dataSources)
                                                                                  )) * UpLinkDownLinkRate.BITS_PER_BYTE);
                }

                return(true);
            }

            return(false);
        }
        private void streamData(object sender, ElapsedEventArgs e)
        {
            streamTimer.Interval = streamRate;

            DataSources dataSources = new DataSources();

            if (toRun.Count + subscriptions.Count > 0)
            {
                try
                {
                    List <string> entries = new List <string>();

                    APIEntry entry = null;

                    lock (subscriptionLock)
                    {
                        dataSources.vessel = kspAPI.getVessel();

                        //Only parse the paused argument if the active vessel is null
                        if (dataSources.vessel != null)
                        {
                            toRun.UnionWith(subscriptions);

                            foreach (string s in toRun)
                            {
                                DataSources dataSourcesClone = dataSources.Clone();
                                string      trimedQuotes     = s.Trim();
                                string      refArg           = trimedQuotes;
                                kspAPI.parseParams(ref refArg, ref dataSourcesClone);

                                kspAPI.process(refArg, out entry);

                                if (entry != null)
                                {
                                    dataSourcesClone.setVarName(trimedQuotes);
                                    entries.Add(entry.formatter.format(entry.function(dataSourcesClone), dataSourcesClone.getVarName()));
                                }
                            }

                            toRun.Clear();

                            if (entry != null)
                            {
                                WebSocketFrame frame  = new WebSocketFrame(ASCIIEncoding.UTF8.GetBytes(entry.formatter.pack(entries)));
                                byte[]         bFrame = frame.AsBytes();
                                dataRates.addDownLinkPoint(System.DateTime.Now, bFrame.Length * UpLinkDownLinkRate.BITS_PER_BYTE);
                                clientConnection.Send(bFrame);
                            }
                        }
                        else
                        {
                            sendNullMessage();
                        }
                    }
                }
                catch (NullReferenceException)
                {
                    PluginLogger.debug("Swallowing null reference exception, potentially due to async game state change.");
                    sendNullMessage();
                }
                catch (Exception ex)
                {
                    PluginLogger.debug("Closing socket due to potential client disconnect:" + ex.GetType().ToString());
                    close();
                }
            }
            else
            {
                sendNullMessage();
            }
        }
Esempio n. 3
0
        }     // OnMessage

        /// Read all variables and send back the responses for just this client
        public void SendDataUpdate()
        {
            // Don't do anything if we are e.g. still awaiting data to be fully set
            if (!readyToSend)
            {
                return;
            }
            lastUpdate = UnityEngine.Time.time;

            // Grab all of the variables at once
            string[] allVariables;
            lock (dataLock)
            {
                allVariables = subscriptions.Union(oneShotRuns).Union(binarySubscriptions).ToArray();
                oneShotRuns.Clear();
            }

            var vessel = api.getVessel();

            // Now, process them all into a data dictionary
            var apiResults = new Dictionary <string, object>();
            var unknowns   = new List <string>();
            var errors     = new Dictionary <string, string>();

            foreach (var apiString in allVariables)
            {
                try
                {
                    apiResults[apiString] = api.ProcessAPIString(apiString);
                }
                catch (IKSPAPI.UnknownAPIException)
                {
                    // IF we get this message, we know it was because no variable was found
                    unknowns.Add(apiString);
                } catch (IKSPAPI.VariableNotEvaluable)
                {
                    // We can't evaluate this at the moment. Just ignore until we can.
                } catch (Exception ex)
                {
                    errors[apiString] = ex.ToString();
                }
            }
            if (unknowns.Count > 0)
            {
                apiResults["unknown"] = unknowns;
            }
            if (errors.Count > 0)
            {
                apiResults["errors"] = errors;
            }

            // Handle sending a binary packet if requested
            if (binarySubscriptions.Length > 0)
            {
                var variableValues = new List <float>();
                // Read every binary value
                foreach (var name in binarySubscriptions)
                {
                    try {
                        variableValues.Add(Convert.ToSingle(apiResults[name]));
                    } catch (Exception ex)
                    {
                        variableValues.Add(0);
                        if (apiResults.ContainsKey(name))
                        {
                            errors[name] = "Error streaming to binary " + name + "='" + apiResults[name] + "'; " + ex.ToString();
                        }
                        else
                        {
                            errors[name] = "Error streaming to binary: value for " + name + " not found; " + ex.ToString();
                        }
                    }
                }
                // Which byte translation?
                Func <float, IEnumerable <byte> > reverser = x => BitConverter.GetBytes(x).Reverse();
                var byteTranslation = BitConverter.IsLittleEndian ? reverser : BitConverter.GetBytes;

                // Now translate these to binary bytes
                var byteData = new List <byte>();
                byteData.Add(1);
                byteData.AddRange(variableValues.SelectMany(x => byteTranslation(x)));
                SendAsync(byteData.ToArray(), x => { });
            }

            //if (allVariables.Contains("binaryNavigation"))
            //{
            //    allVariables = allVariables.Where(x => x != "binaryNavigation").ToArray();
            //    // Build and dispatch the binary information, here and quickly....
            //    var pitch = Convert.ToSingle(api.ProcessAPIString("n.pitch"));
            //    var roll = Convert.ToSingle(api.ProcessAPIString("n.roll"));
            //    var heading = Convert.ToSingle(api.ProcessAPIString("n.heading"));
            //    var deltaV = Convert.ToSingle(api.ProcessAPIString("v.verticalSpeed"));
            //    var parts = new List<byte[]>();
            //    parts.Add(new byte[] { 1 });
            //    parts.Add(BitConverter.GetBytes(heading));
            //    parts.Add(BitConverter.GetBytes(pitch));
            //    parts.Add(BitConverter.GetBytes(roll));
            //    parts.Add(BitConverter.GetBytes(deltaV));
            //    if (BitConverter.IsLittleEndian) parts = parts.Select(x => x.Reverse().ToArray()).ToList();
            //    var byteData = parts.SelectMany(x => x).ToArray();
            //    SendAsync(byteData, x => { });
            //    PluginLogger.print(string.Format("Send byte data for {0}, {1}, {2}, {3}", heading, pitch, roll, deltaV));
            //}

            var data = SimpleJson.SimpleJson.SerializeObject(apiResults);

            // Now, if we have data send a message, otherwise send a null message
            readyToSend = false;
            try
            {
                SendAsync(data, (b) => readyToSend = true);
                dataRates.SendDataToClient(data.Length);
            }
            catch (Exception ex)
            {
                PluginLogger.print("Caught " + ex.ToString());
            }
            finally
            {
                readyToSend = true;
            }
        }