Heres the scenario : Ive got a struct to represent 5 client nodes in a system, the client nodes send packets to the server node every 2 seconds. A GUI is created to properly display values from the client. The problem im having is representing a client offline on the GUI. The suggestion is use a timer (on every packet received from a specific client) set to 5 seconds and if the GUI does not receive a packet from that client then zero all figures representing that client. Heres my attempt :

public partial class form1 : Form
    {
        string rxstring;
        string[] ip4c;
        int numberofcl;
        System.Windows.Forms.Timer _timer = new System.Windows.Forms.Timer();
       // System.Windows.Forms.Timer[] timer = new System.Windows.Forms.Timer[5

        public struct Node
        {
           public string ip4;
           public double temp;
             public double battery;
             public string light;

            public Node (double x,double y,string d, string i)
            {
              ip4 = i;
                temp = x;
                battery = y;
                light = d;

            }
        }

        List<Node> nodes = new List<Node>();

        public form1()
        {
            InitializeComponent();

        }

        private void startbtn_Click(object sender, EventArgs e)
        {
            serialport.BaudRate = 115200;
            serialport.PortName = combox.Text;
            //serialport.open;
            if (!serialport.IsOpen)
            {

                serialport.Open();
                startbtn.Enabled = false;
                stopbtn.Enabled = true;
                refreshbtn.Enabled = true;


            }




        }

        private void Form1_Load(object sender, EventArgs e)
        {
            startbtn.IsAccessible = false;
            stopbtn.IsAccessible = false;
            numberofcl = 0;
            string[] ports = SerialPort.GetPortNames();
            foreach (string port in ports)
            {
                combox.Items.Add(port); 
            }
            ip4c = new string[] {"F30F","F428","F52C","3772","F29A"};



        }

        private void combox_SelectedIndexChanged(object sender, EventArgs e)
        {
            startbtn.Enabled = true;
        }

        private void serialport_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                rxstring = serialport.ReadLine();
                this.BeginInvoke(new EventHandler(DisplayText));
            }
            catch (System.Exception ex)
            {

                Console.WriteLine(ex.Message);

            }
        }

        private void DisplayText(object sender, EventArgs e)
        {
            string d;
            int len = 7;
            rxtxtbx.AppendText(rxstring+"\n\r");
           // rxtxtbx2.AppendText(rxstring.Substring(0, 1));
            if (rxstring.Length > len)
            {
                if (rxstring.Substring(1, len) == "Number ") 
                {
                    int i = rxstring.IndexOf("Number ");
                    string j = rxstring.Substring(i); //takes whole string line into j
                    string[] jj = j.Split(new char[] { '=' });
                    numofcl.Text = Convert.ToString(jj[1]);
                }


                if (rxstring.Substring(1, len) == "Average")
                {
                    int i = rxstring.IndexOf("Average");
                    d = rxstring.Substring(i);
                   // rxtxtbx2.AppendText(d+"\n");

                }

                else {

                    //rxtxtbx2.AppendText(rxstring.Substring(0, len)+"\n");
                }
            }
            if (rxstring.Length > len)
            {
                double avgtemp, avglight;
                double sumtemp =0;
                double sumlight = 0;

                //string j = rxstring;
                int i = rxstring.IndexOf("<Node>");
                string j = rxstring.Substring(i);
                string[] jj = j.Split(new char[] { '|' } , StringSplitOptions.None);

                string[] ip4 = jj[1].Split(new char[] { ':' }, StringSplitOptions.None);

                string IP = ip4[5].ToUpper();       // Last four octects of the ipv6 address
                double temp = Convert.ToDouble(jj[2]);
                string light = jj[3];
                double battery = Convert.ToDouble(jj[4]);

                battery = (battery / 1810) * 100;

                Node tempnode = new Node(temp, battery, light, IP);
                if (nodes.Count == 0)
                {
                    nodes.Add(tempnode);
                    updatefield(tempnode.ip4, tempnode);
                }
                else
                {
                   //foreach (Node n in nodes) {
                    for(int z = 0; z < nodes.Count(); z++)
                    {
                        if (IP == nodes[z].ip4)
                        {

                            Node tempnode2 = new Node(temp,battery,light,IP);
                            nodes.Remove(nodes[z]);
                            nodes.Add(tempnode2);
                            updatefield(tempnode.ip4, tempnode2);
                            //updatefield(n.ip4);
                            // nodes[z].light = light;
                        }
                        else
                        {
                            nodes.Add(tempnode);
                            updatefield(tempnode.ip4, tempnode);
                        }
                        sumtemp += nodes[z].temp;
                        sumlight += Convert.ToDouble( nodes[z].light);



                    }
                }
                numberofcl = nodes.Count();
                numofcl.Text = Convert.ToString(numberofcl);
                avgtemp = sumtemp / numberofcl;
                avglight = sumlight / numberofcl;
                label4.Text = DecimalPlaceNoRounding(avgtemp, 2);
                label6.Text = DecimalPlaceNoRounding(avglight, 2);


              //  richTextBox1.AppendText(IP + "\n");


                //richTextBox1.AppendText(ip4[5] + "\n");
                //foreach (string x in ip4c)
                //for (int l = 0; l < 5;l++)
                //{
                //    int c = string.Compare(ip4[5], ip4c[l]);
                //    if (c == 0)
                //    {
                //      //  updatefield(l, jj);
                //    }
                //}
            }
        }



        private void stopbtn_Click(object sender, EventArgs e)
        {
            if (!serialport.IsOpen)
            {
                serialport.Close();
            }
        }



        string DecimalPlaceNoRounding(double d, int decimalPlaces = 2)
        {
            d = d * Math.Pow(10, decimalPlaces);
            d = Math.Truncate(d);
            d = d / Math.Pow(10, decimalPlaces);
            return string.Format("{0:N" + Math.Abs(decimalPlaces) + "}", d);
        }

        private void updatefield(String ip4oc, Node jj)//string[] jj) "F30F","F428","F52C","3772","F29A"
        {
            try
            {
                switch (ip4oc)
                {

                    case "F30F":
                        node1temptxt.Text = DecimalPlaceNoRounding(jj.temp, 2);
                        node1brighttxt.Text = DecimalPlaceNoRounding(Convert.ToDouble(jj.light), 2);
                        node1vddtxt.Text = DecimalPlaceNoRounding(jj.battery, 2);
                        break;
                    case "F428":
                        node3temptxt.Text = DecimalPlaceNoRounding(jj.temp, 2);
                        node3brighttxt.Text = DecimalPlaceNoRounding(Convert.ToDouble(jj.light), 2);
                        node3vddtxt.Text = DecimalPlaceNoRounding(jj.battery, 2);
                        break;
                    case "F52C":
                        node2temptxt.Text = DecimalPlaceNoRounding(jj.temp, 2);
                        node2brighttxt.Text = DecimalPlaceNoRounding(Convert.ToDouble(jj.light), 2);
                        node2vddtxt.Text = DecimalPlaceNoRounding(jj.battery, 2);
                        break;
                    case "3772":
                        node4temptxt.Text = DecimalPlaceNoRounding(jj.temp, 2);
                        node4brighttxt.Text = DecimalPlaceNoRounding(Convert.ToDouble(jj.light), 2);
                        node4vddtxt.Text = DecimalPlaceNoRounding(jj.battery, 2);
                        break;
                    case "F29A":
                        node5temptxt.Text = DecimalPlaceNoRounding(jj.temp, 2);
                        node5brighttxt.Text = DecimalPlaceNoRounding(Convert.ToDouble(jj.light), 2);
                        node5vddtxt.Text = DecimalPlaceNoRounding(jj.battery, 2);
                        break;
                }
            }
            catch (System.Exception ex)
            {
                //

            }
        }

But i cant see to get my head around adding the timer to the struct so every client has its own timer in order to check if it is online or not. Please help but I am a noob so please lay it easy on me

Edited 3 Years Ago by pritaeas: Fixed title.

You'll probably be better off using a class for this instead of a struct, and add a timer and a counter as properties of the class:

    public class Node
    {
        public string ip4 = "";
        public double temp = 0.0;
        public double battery = 0.0;
        public string light = "";
        public string Name = "";
        public Timer nodetimer = new Timer();
        public int elapsedtime = 0;

        public Node(double x, double y, string d, string i, string name)
        {

            Name = name;
            ip4 = i;
            temp = x;
            battery = y;
            light = d;                
        }

    }

Then when you add a new node to the list add a common handler for the timer's tick event:

    List<Node> nodelist = new List<Node>();       
    public Form1()
    {
        for (int i = 1; i < 4; i++)
        {
            Node tempnode = new Node(0.0,0.0,"","",i.ToString());
            tempnode.nodetimer.Tick += new System.EventHandler(nodetimer_tick);
            tempnode.nodetimer.Tag = tempnode.Name;
            tempnode.nodetimer.Interval = 1000;
            tempnode.nodetimer.Start();
            nodelist.Add(tempnode);
        }
    }

The handler routine could look somthing like this:

    private void nodetimer_tick(object sender, EventArgs e)
    {
        Node currentnode = nodelist.Find(n => n.Name == ((Timer)sender).Tag.ToString());
        currentnode.elapsedtime++;
    }

I added a name property this allows you to have a simple way to identify the node. This code is barebones, you'll have to flesh it out with a check on whether the counter has reached the limit and the code you want to run when it does.

Edited 3 Years Ago by tinstaafl

I would personally do it the other way around and have a global single timer instance.

On your class have a DateTime LastCheckIn and update this everytime your client sends to the server.

In your global timer event, iterate through each client object you have and see if LastCheckIn is beyond a certain value (5 seconds I think you mentioned), mark all instances to be zero'd. Another background thread can pick up the instances (possibly event driven) that need to be deleted.

This article has been dead for over six months. Start a new discussion instead.