C# websocket

C# example repository can be found from https://bitbucket.org/timetopic/timetopic-logger-csharp-api-example/src. Example tested with VC2017 community.

Example contains sample API for TimeToPic Events, states and ValueAbs. Messages are sent over websocket (websocket-sharp.2.0.13).

On example, there are various cases bundled into one. Basically sample starts several threads and send items. Please have a look snippets below and you get complete understanding how example works. Screenshots are end of article.

 try {

                for (int k = 0; k < defaultIterationsForExample; k++)
                {
                    // payload work. Event that has startAnd stop 
                    Stopwatch sw = new Stopwatch();
                    sw.Start();

                    PerformEventExample(defaultJobMaxWaitTimeMs, defaultMaxSleepTimeMsAfterJob, myEvent);
                    PerformStateMachineExample();

                    sw.Stop();
                    int durMs = (int)sw.Elapsed.TotalMilliseconds;
                    TimeToPicLogger.LogValue(durMs, myEvent + " duration(ms)");
                }

                string msg = "Thread #" + threadId.ToString() + " completed" + Environment.NewLine;
                Console.Write(msg);
            }
            catch (ThreadAbortException)
            {
                string msg = "Thread #" + threadId.ToString() + " aborted" + Environment.NewLine;
                Console.Write(msg);
            }
        private static void PerformStateMachineExample()
        {
            const int maxStateId = 5;
            Random rnd = new Random();
            int nexState = rnd.Next(1, maxStateId);
            var threadId = Thread.CurrentThread.ManagedThreadId;
            //var threadId = Thread.CurrentThread.ManagedThreadId % 3; // if Testing how graphViz visualizer works, limit amount of machine to 2

            string nextState = "st#" + nexState.ToString();
            string machineName = "machine #" + threadId.ToString()+ " state machine";

            TimeToPicLogger.LogState(nextState, machineName);            
        }
        private static void PerformEventExample(int defaultJobMaxWaitTimeMs, int defaultMaxSleepTimeMsAfterJob, string myEvent)
        {
            TimeToPicLogger.LogEventStart(myEvent);     // start event. This is used for measurement
            Random rnd = new Random();
            int jobTimeTimeMs = rnd.Next(1, defaultJobMaxWaitTimeMs);
            Thread.Sleep(jobTimeTimeMs);            // do simulated work 
            TimeToPicLogger.LogEventStop(myEvent);      // stop event. This stops measurement

            Random rnd2 = new Random();
            int sleepTimeMs = rnd2.Next(1, defaultMaxSleepTimeMsAfterJob);
            Thread.Sleep(sleepTimeMs);
        }

Logging API functions will have following implementations:

public static void LogEventStart(string eventName)
        {
            string logLine = getTimeStamp().ToString() + ";event;start;" + eventName + Environment.NewLine;            
            send(logLine);
        }

        public static void LogEventStart(string eventName, string comment)
        {
            string logLine = getTimeStamp().ToString() + ";namedevent;start;" + eventName +";"+comment +              Environment.NewLine;
            send(logLine);
        }

        public static void LogEventStop(string eventName)
        {
            string logLine = getTimeStamp()+ ";event;stop;" + eventName + Environment.NewLine;
            send(logLine);
        }

        public static void LogState(string newState, string machineName)
        {
            // https://timetopic.herwoodtechnologies.com/documentation/file-format
            //12.003;state;running;testchannel\n
            string logLine = getTimeStamp() + ";state;" + newState + ";" + machineName + Environment.NewLine;
            send(logLine);
        }

        public static void LogValue(int valueToBeLogged, string nameOfValue)
        {
            // https://timetopic.herwoodtechnologies.com/documentation/file-format
            // 2014/02/11 21:35:27.000;valueabs;7;VALUEABS_example
            string logLine = getTimeStamp() + ";valueabs;"+ valueToBeLogged.ToString()+";" + nameOfValue + Environment.NewLine;
            send(logLine);
        }

Those functions will forward strings simply to socket:

        private static void send(string logLine)
        {
            SocketLogger.SendSocket(logLine);
        }

And timestamp format will be:


private static string getTimeStamp()
        {
            // https://timetopic.herwoodtechnologies.com/documentation/file-format
            double milliseconds = (DateTime.Now - sStartTime).TotalMilliseconds;
            double secs = milliseconds / 1000.0;            
            sNfi.NumberDecimalSeparator = ".";
            string ret = secs.ToString(sNfi);
            return ret;
        }

Running sample

Compile example, start TimeToPic Logger, TimeToPic and start example. You should start seeing sample log lines on Logger.

Seeing all in Timeline

Click Show on TimeToPic icon on TimeToPic Logger and you should see all data on timeline. Picture is bit messy so filtering makes it more clear.

Filtering only events

Type "event" to TimeToPic event box and use "e" key sort to events in order of appearance from current cursor position.

Filtering only state machines

Clear filter and type "state" and you see state machine channels only.