예제 #1
0
        protected void Start(Action action, int retryAttempts = 3)
        {
            String monitorId = "Monitor-" + ID;
            int    attempts  = 0;

            while (true)
            {
                if (ThreadExecutionManager.IsEmpty(ID) && ThreadExecutionManager.IsEmpty(monitorId))
                {
                    _startXS = ThreadExecutionManager.Execute(ID, action);
                    if (_startXS == null)
                    {
                        throw new Exception("Connection::Start: Unable to create thread for connection " + ID);
                    }
                    _monitorXS = ThreadExecutionManager.Execute(monitorId, this.Monitor);
                    Tracing?.TraceEvent(TraceEventType.Verbose, 2000, "Connection::Start: Created execution thread {0} and monitor thrad{1}", ID, monitorId);

                    break;
                }
                else
                {
                    if (++attempts > retryAttempts)
                    {
                        var sxs = ThreadExecutionManager.GetExecutionState(ID);
                        var mxs = ThreadExecutionManager.GetExecutionState(monitorId);
                        throw new Exception("Thread ID " + ID + " has state " + sxs.State + " and " + monitorId + " has state " + mxs.State);
                    }
                    System.Threading.Thread.Sleep(200);
                }
            }
        }
        virtual public byte ThreadExecuteCommand(String command, int repeat, int delay, List <Object> args)
        {
            //check has command
            ArduinoCommand acmd = GetCommand(command);

            if (acmd == null)
            {
                throw new Exception(String.Format("Device {0} does not have command {1}", ID, command));
            }

            //pass an empty array rather than null ... safety measure here just for the ThreadExecution Manager
            if (args == null)
            {
                args = new List <Object>();
            }

            byte tag = acmd.ExpectsResponse ? Mgr.MessageTags.CreateTag() : (byte)0;
            ExecutionArguments xargs = new ExecutionArguments(args, tag);

            //Use ThreadExecutionManager to allow for multi-threading by device
            int prevSize = ThreadExecutionManager.MaxQueueSize;

            ThreadExecutionManager.MaxQueueSize = acmd.IsCompound ? 1 : 256;
            ThreadExecutionState xs = ThreadExecutionManager.Execute <ExecutionArguments>(ID, repeat, delay, ExecuteCommand, command, xargs);

            ThreadExecutionManager.MaxQueueSize = prevSize;
            if (xs == null)
            {
                Mgr.MessageTags.Release(tag);
                tag = 0;
            }

            return(tag);
        }
예제 #3
0
        public override void HandleDigitalPinStateChange(int pinNumber, bool newState)
        {
            if (pinNumber != _sensorPin)
            {
                throw new Exception(String.Format("State changed on pin {0} but sensor is attached to pin {1}", pinNumber, _sensorPin));
            }

            //we keep a record of the raw data so if we re-enable then we can re-create a state change event
            _rawState = newState;
            if (!Enabled)
            {
                return;
            }

            if (newState != _latestState)
            {
                lock (_stateLock)
                {
                    _latestState = newState;
                }
                if (_noiseThreshold > 0)
                {
                    ThreadExecutionManager.Execute <bool>(ID, VerifyStateChange, _latestState);
                }
                else
                {
                    OnStateChange(_latestState);
                }
            }
        }
예제 #4
0
        override protected void HandleReceivedMessage(Message message)
        {
            base.HandleReceivedMessage(message);

            Message response = null;

            switch (message.Type)
            {
            case MessageType.TRACE:
                _tracing2Client = true;
                HandleMessage?.Invoke(this, message);
                break;

            case MessageType.PING:
                response = CreatePingResponse(message);
                SendMessage(response);
                break;

            case MessageType.STATUS_REQUEST:
                response = CreateStatusResponse(message);
                SendMessage(response);
                break;

            case MessageType.SUBSCRIBE:
                if (message.HasValue("Subscriber"))
                {
                    try
                    {
                        AddSubscriber(ConnectionManager.Subscriber.Parse(message.GetString("Subscriber")));
                    }
                    catch (Exception e)
                    {
                        Tracing?.TraceEvent(TraceEventType.Error, 2000, e.Message);
                    }
                }
                break;

            case MessageType.UNSUBSCRIBE:
                if (message.HasValue("Subscriber"))
                {
                    RemoveSubscriber(message.GetString("Subscriber"));
                }
                break;

            default:
                int priorSize = ThreadExecutionManager.MaxQueueSize;
                ThreadExecutionManager.MaxQueueSize = 256;
                ThreadExecutionManager.Execute <Message>("HandleMessage-" + ID, HandleMessageDelegateWrapper, message);
                ThreadExecutionManager.MaxQueueSize = priorSize;
                break;
            }
        }
예제 #5
0
        protected void Monitor()
        {
            while (true)
            {
                System.Threading.Thread.Sleep(500); //TODO: should make this value settable
                //Console.WriteLine("Monitoring connection " + ID + " has state " + State);
                if (_startXS != null && _startXS.IsFinished)
                {
                    Tracing?.TraceEvent(TraceEventType.Warning, 2000, "Connection::Monitor: Exeuction thread for {0} is of state {1} but connection is of state {2} so setting connection state to closed.", ToString(), _startXS.State, State);
                    State = ConnectionState.CLOSED;
                }

                if (TimedOut(ConnectionTimeout, ConnectionState.OPENED))
                {
                    Tracing?.TraceEvent(TraceEventType.Warning, 2000, "Connection::Monitor: Connection timeout {0} for {1}", ConnectionTimeout, ToString());
                    OnConnectionTimeout();
                }

                if (TimedOut(ActivityTimeout, ConnectionState.CONNECTED))
                {
                    Tracing?.TraceEvent(TraceEventType.Warning, 2000, "Connection::Monitor: Activity timeout {0} for {1}", ActivityTimeout, ToString());
                    OnActivityTimeout();
                }
                if (State == ConnectionState.CLOSED)
                {
                    if (_startXS != null)
                    {
                        if (!_startXS.IsFinished)
                        {
                            Tracing?.TraceEvent(TraceEventType.Information, 2000, "Connection::Monitor: Connection is of state closed but execution thread is not finished so terminating.");
                            ThreadExecutionManager.Terminate(_startXS.ID);
                        }
                        else if (_startXS.Exceptions.Count > 0)
                        {
                            foreach (var ex in _startXS.Exceptions)
                            {
                                Tracing?.TraceEvent(TraceEventType.Error, 2000, "Connection::Monitor: Connction is of state closed with exception {0}", ex.Message);
                            }
                        }
                    }
                    break;
                }
            }
        }
예제 #6
0
        private void SendMessage(String sendType = null)
        {
            System.Diagnostics.Debug.Print("Send message");

            try
            {
                if (sendType == null)
                {
                    if (cmbSendType.SelectedItem != null)
                    {
                        sendType = cmbSendType.SelectedItem.ToString();
                    }
                }

                if (sendType == null || sendType == String.Empty)
                {
                    throw new Exception("No send type provided");
                }

                String target = null;
                if (listViewClients.SelectedItems != null && listViewClients.SelectedItems.Count > 0)
                {
                    target = listViewClients.SelectedItems[0].Name;
                }
                ClientConnection client      = appCtx.CurrentClient;
                String           commandLine = tbCommandLine.Text;
                List <String>    clArgs      = commandLine.Split(' ').ToList();

                if (client == null)
                {
                    throw new Exception("No client from which to send");
                }

                switch (sendType.Trim().ToUpper())
                {
                case "PING":
                    MessageSent = client.SendPing(target);
                    break;

                case "STATUS REQUEST":
                    if (target == null)
                    {
                        MessageSent = client.RequestServerStatus();
                    }
                    else
                    {
                        MessageSent = client.RequestClientConnectionStatus(target);
                    }
                    break;

                case "SUBSCRIBE":
                    if (target == null)
                    {
                        throw new Exception("Please select client to subscribe to");
                    }
                    else
                    {
                        MessageSent = client.Subscribe(target);
                    }
                    break;

                case "UNSUBSCRIBE":
                    if (target == null)
                    {
                        throw new Exception("Please select client to unsubscribe from");
                    }
                    else
                    {
                        MessageSent = client.Unsubscribe(target);
                    }
                    break;

                case "COMMAND":
                    if (target != null)
                    {
                        var    cmd     = clArgs[0];
                        var    cmdArgs = clArgs.Count > 1 ? clArgs.GetRange(1, clArgs.Count - 1).ToList <Object>() : null;
                        int    repeat  = 1;
                        int    delay   = 0;
                        String rd      = tbRepeatDelay.Text;
                        if (rd != null && rd != String.Empty)
                        {
                            String[] ar = rd.Split(':');
                            repeat = ar.Length > 0 ? System.Convert.ToInt32(ar[0]) : 1;
                            delay  = ar.Length > 1 ? System.Convert.ToInt32(ar[1]) : 0;
                        }
                        ThreadExecutionManager.Execute <List <Object> >("ccmdCMM", repeat, delay, SendClientCommand, target, cmd, cmdArgs);
                    }
                    else
                    {
                        throw new Exception("Use server tab to send commands to server");
                    }
                    break;

                default:
                    throw new Exception("Send type " + sendType + " not recognised");
                }

                UpdateMessageSentDetails();
            } catch (Exception e)
            {
                HandleException(e);
            }
        }