/// <summary>
        /// Transmits the UDP ping or ping reply message configured for this instance of NiawaAdHocNetworkAdapter.
        /// </summary>
        /// <param name="isReplyMessage">True if ping reply message; False if ping message</param>
        public void TransmitPingMessage(bool isReplyMessage, string replySerialID)
        {
            try
            {
                if(!isReplyMessage )
                {
                    logger.Info("[" + _description + "-M] Transmitting ping message");

                    //send message
                    _evtRaiser.RaiseEvent("Message", "Transmitting ping message", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                    _threadStatus.MessageCount += 1;

                    /*broadcast UDP ping when requested by implementor*/
                    if (!_started) throw new Exception("[" + _description + "-M] Could not transmit ping message: NiawaAdHocNetworkAdapter is not started");

                    if (_tcpHandshakePort == 0) throw new Exception("[" + _description + "-M] Could not transmit ping message: HandshakePort [" + _tcpHandshakePort + "] is not valid.");

                    //create message
                    MessageContent.PingMessageContent pingMessage = new MessageContent.PingMessageContent(_ipAddress, _hostname, string.Empty);

                    NiawaNetDatagram message = new NiawaNetDatagram(_ipAddress, _udpPort, Guid.NewGuid(), _hostname, _applicationName, MessageContent.PingMessageContent.MESSAGE_CONTENT_TYPE_PING, pingMessage.ToJson());

                    //send message
                    _udpTransmitter.SendMessage(message);

                }

                else
                {
                    logger.Info("[" + _description + "-M] Transmitting ping reply message");

                    //send message
                    _evtRaiser.RaiseEvent("Message", "Transmitting ping reply message", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                    _threadStatus.MessageCount += 1;

                    /*broadcast UDP ping reply when requested by implementor*/
                    if (!_started) throw new Exception("[" + _description + "-M] Could not transmit ping reply message: NiawaAdHocNetworkAdapter is not started");

                    if (_tcpHandshakePort == 0) throw new Exception("[" + _description + "-M] Could not transmit ping reply message: HandshakePort [" + _tcpHandshakePort + "] is not valid.");

                    //create message
                    MessageContent.PingMessageContent pingMessage = new MessageContent.PingMessageContent(_ipAddress, _hostname, replySerialID);

                    NiawaNetDatagram message = new NiawaNetDatagram(_ipAddress, _udpPort, Guid.NewGuid(), _hostname, _applicationName, MessageContent.PingMessageContent.MESSAGE_CONTENT_TYPE_PINGREPLY, pingMessage.ToJson());

                    //send message
                    _udpTransmitter.SendMessage(message);

                }

            }
            catch (Exception ex)
            {
                logger.Error("[" + _description + "-M] Error while transmitting ping/ping reply message: " + ex.Message, ex);
                throw ex;
            }
        }
        /// <summary>
        /// Raises event with current status
        /// </summary>
        /// <returns></returns>
        /*public string RaiseStatusReport()
        {
            try
            {
                if (_started)
                {
                    _evtRaiser.RaiseEvent("StatusReport", "Started", string.Empty);
                    return "Started";
                }
                else
                {
                    _evtRaiser.RaiseEvent("StatusReport", "Stopped", string.Empty);
                    return "Stopped";
                }
            }
            catch (Exception ex)
            {
                logger.ErrorException("[" + _description + "-M] Error while raising status report: " + ex.Message, ex);
                throw ex;
            }

        }
        */
        /// <summary>
        /// Raises an event with thread health information passed in by the caller.  This function is utilized in the ThreadHealthMonitor object.
        /// </summary>
        /// <param name="description"></param>
        /// <param name="threadHealthValue"></param>
        /// <param name="healthFailed"></param>
        /*public void RaiseThreadHealth(string description, double threadHealthValue, bool healthFailed)
        {
            try
            {
                _evtRaiser.RaiseEvent("ThreadHealth", "Description:" + description + ";TheadHealth:" + threadHealthValue.ToString("F") + ";HealthFailed:" + healthFailed.ToString(), string.Empty);
            }
            catch (Exception ex)
            {
                logger.ErrorException("[" + _description + "-M] Error while raising thread health: " + ex.Message, ex);
                throw ex;
            }

        }
        */
        /// <summary>
        /// Transmits the UDP handshake message configured for this instance of NiawaAdHocNetworkAdapter.
        /// </summary>
        public void TransmitHandshakeMessage()
        {
            try
            {
                logger.Info("[" + _description + "-M] Transmitting handshake message");

                //send message
                _evtRaiser.RaiseEvent("Message", "Transmitting handshake message", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                _threadStatus.MessageCount += 1;

                /*broadcast UDP handshake when requested by implementor*/
                if (!_started) throw new Exception("[" + _description + "-M] Could not transmit handshake message: NiawaAdHocNetworkAdapter is not started");

                if (_tcpHandshakePort == 0) throw new Exception("[" + _description + "-M] Could not transmit handshake message: HandshakePort [" + _tcpHandshakePort + "] is not valid.");

                //create message
                MessageContent.HandshakeMessageContent handshakeMessage = new MessageContent.HandshakeMessageContent(_ipAddress, _hostname, _tcpHandshakePort);
                //handshakeMessage.IpAddress = _ipAddress;
                //handshakeMessage.Hostname = _hostname;
                //handshakeMessage.HandshakePort = _tcpHandshakePort;

                NiawaNetDatagram message = new NiawaNetDatagram(_ipAddress, _udpPort, Guid.NewGuid(), _hostname, _applicationName, MessageContent.HandshakeMessageContent.MESSAGE_CONTENT_TYPE, handshakeMessage.ToJson());

                //send message
                _udpTransmitter.SendMessage(message);

            }
            catch (Exception ex)
            {
                logger.Error("[" + _description + "-M] Error while transmitting handshake message: " + ex.Message, ex);
                throw ex;
            }
        }
Example #3
0
        //public UdpTransmitter(int port, Niawa.MsEventController.EventConsumer evtConsumer, Niawa.Utilities.UtilsServiceBus utilsBus, string applicationNameDetailed, Niawa.Utilities.SerialId parentThreadId)
        //{
        //    try
        //    {
        //        _applicationNameDetailed = applicationNameDetailed;
        //        _port = port;
        //        _evtConsumer = evtConsumer;
        //        _sendQueue = new Queue<NiawaNetDatagram>();
        //        lockSection = new System.Threading.Semaphore(1, 1);
        //        _description = "UdpTransmitter " + _port.ToString();
        //        //initialize the endpoints
        //        _groupEndpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Broadcast, _port);
        //        _localEP = new System.Net.IPEndPoint(System.Net.IPAddress.Loopback, _port);
        //        //initialize serial ID generator
        //        id = utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_NET_DATAGRAM);
        //        //initialize event logging
        //        _evtRaiser = new MsEventController.EventRaiser("UdpTransmitter", _applicationNameDetailed, _description, utilsBus);
        //        if (_evtConsumer != null) _evtRaiser.AddEventConsumer(_evtConsumer);
        //        _threadStatus = new Niawa.Threading.ThreadStatus(_description, 60, utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_THREAD_ID), parentThreadId, _evtRaiser);
        //        //thread status
        //        _threadStatus.Status = Niawa.Threading.ThreadStatus.STATUS_INITIALIZED;
        //        //add thread elective properties.
        //        _threadStatus.AddElectiveProperty("Port", _port.ToString());
        //    }
        //    catch (Exception ex)
        //    {
        //        logger.Error("[UdpTransmitter-M] Error while instantiating: " + ex.Message, ex);
        //        throw ex;
        //    }
        //}
        /// <summary>
        /// Send UDP message.
        /// </summary>
        /// <param name="message">Message to send via UDP.</param>
        public void SendMessage(NiawaNetDatagram message)
        {
            try
            {
                if (!_threadStatus.IsThreadEnabled || !_threadStatus.IsThreadActive)
                {
                    _evtRaiser.RaiseEvent("MessageError", "Cannot send message - Transmitter is not active"
                        , Niawa.Utilities.InlineSortedListCreator.CreateStrStr("NiawaNetMessage", message.ToJson())
                        , _threadStatus.NodeID
                        , _threadStatus.ParentNodeID);
                    throw new MessageNotSentException("Cannot send message - transmitter is not active");
                }

                //get next serial ID
                id = Niawa.Utilities.IdGeneratorUtils.IncrementSerialId(id);
                message.SerialID = id.ToString();

                logger.Info("[" + _description + "-M] Queueing message: Type [" + message.MessageType + "] SerialID [" + message.SerialID + "]");
                _sendQueue.Enqueue(message);
            }
            catch (Exception ex)
            {
                logger.Error("[" + _description + "-M] Error while sending message: " + ex.Message, ex);
                throw ex;
            }
        }
Example #4
0
        /// <summary>
        /// Transmit message via UDP.
        /// </summary>
        /// <param name="message">Message to send via UDP.</param>
        /// <returns></returns>
        private bool TransmitMessage(NiawaNetDatagram message)
        {
            bool succeeded = false;

            //attempt lock
            bool tryLock = lockSection.WaitOne(60000);
            if (!tryLock) throw new TimeoutException("[" + _description + "-T] Could not obtain lock while sending message");

            try
            {
                Byte[] messageBytes = message.ToByteArray();

                //send message
                /*v1*/
                //_netUdpClient.Connect(_groupEndpoint);
                //_netUdpClient.Send(messageBytes, messageBytes.Length, _localEP);
                //_netUdpClient.Close();
                //_netUdpClient = null;
                //messageInProgressGuid = string.Empty;

                /*v2*/
                //_netUdpClient.Send(messageBytes, messageBytes.Length, _localEP);

                /*v3*/
                if (messageBytes.Length > 65000)
                {
                    //message is too long
                    throw new InvalidOperationException("UdpTransmitter cannot send a message with length greater than 65000 bytes.");
                }
                else
                {

                    bool tryLock2 = lockSentMessageGuidBuffer.WaitOne(5000);
                    if (tryLock2 == false) throw new TimeoutException("Could not obtain lock on Sent Message GUID Buffer while sending message.");
                    try
                    {
                        //add guid to sent buffer
                        _sentMessageGuidBuffer.Add(message.Guid);
                        if (_sentMessageGuidBuffer.Count > 1000) _sentMessageGuidBuffer.RemoveAt(0);
                    }
                    finally
                    {
                        lockSentMessageGuidBuffer.Release();
                    }

                    //send
                    _netUdpClient.Send(messageBytes, messageBytes.Length);
                }

                succeeded = true;

            }
            catch (Exception ex)
            {
                logger.Error("[" + _description + "-M] Error while transmitting message: " + ex.Message, ex);
                throw ex;
            }
            finally
            {
                //release lock
                lockSection.Release();
            }

            logger.Info("[" + _description + "-T] Message sent: Type [" + message.MessageType + "] SerialID [" + message.SerialID + "] Guid [" + message.Guid.ToString() + "]");

            _evtRaiser.RaiseEvent("Message", "Message sent [" + message.SerialID + "]"
                , Niawa.Utilities.InlineSortedListCreator.CreateStrStr("NiawaNetMessage", message.ToJson())
                , _threadStatus.NodeID
                , _threadStatus.ParentNodeID);
            _threadStatus.MessageCount += 1;

            return succeeded;
        }
Example #5
0
        /// <summary>
        /// Loop thread that reads UDP messages and adds items to the receive queue.
        /// </summary>
        /// <param name="data"></param>
        private void ListenThreadImpl(object data)
        {
            _threadStatus.IsThreadActive = true;
            logger.Info("[" + _description + "-T] Receiver active");

            bool suspendedStateDetectChange = false;

            try
            {
                while (_threadStatus.IsThreadEnabled)
                {

                    _threadStatus.ThreadHealthDate = DateTime.Now;

                    //listening
                    if (suspendedStateDetectChange != _threadSuspended)
                    {
                        suspendedStateDetectChange = _threadSuspended;
                        if (_threadSuspended == true) { logger.Info("[" + _description + "-T] Receiver suspended"); }
                        if (_threadSuspended == false) { logger.Info("[" + _description + "-T] Receiver resumed"); }
                    }

                    if (_threadSuspended)
                    {
                        //suspended
                        //logger.Debug("[" + _description + "] Receiver suspended");
                        System.Threading.Thread.Sleep(10);
                    }
                    else
                    {
                        //not suspended
                        bool receivingMessage = false;

                        try
                        {
                            logger.Info("[" + _description + "-T] Waiting for network data");
                            //get datagram
                            /*v2*/
                            //Byte[] recvBytes = _netUdpClient.Receive(ref _recvEndpoint);

                            /*v3*/
                            Byte[] recvBytes = new Byte[65000];
                            int ix = _netUdpClient.Receive(recvBytes);
                            Array.Resize<Byte>(ref recvBytes, ix);

                            logger.Info("[" + _description + "-T] Received network data");
                            receivingMessage = true;
                            NiawaNetDatagram message;
                            //get message contents
                            message = new NiawaNetDatagram(recvBytes);

                            //check if message should be ignored
                            if (_ignoreTransmittedUdpMessages && _udpTransmitter != null && _udpTransmitter.SentMessageGuidBufferContainsGuid(message.Guid))
                            {
                                //ignore message
                                logger.Info("[" + _description + "-T] Ignoring message sent by associated UdpTransmitter: Type [" + message.MessageType + "] SerialID [" + message.SerialID + "]");

                            }
                            else
                            {
                                //don't ignore message
                                //attempt lock
                                bool tryLock = lockSection.WaitOne(60000);
                                if (!tryLock) throw new TimeoutException("[" + _description + "-T] Could not obtain lock while receiving message");

                                try
                                {
                                    //add message to queue
                                    _receiveQueue.Enqueue(message);
                                }
                                finally
                                {
                                    //release lock
                                    lockSection.Release();
                                }

                                //raise event
                                _threadStatus.MessageCount += 1;
                                logger.Info("[" + _description + "-T] Received message: Type [" + message.MessageType + "] SerialID [" + message.SerialID + "]");

                                _evtRaiser.RaiseEvent("Message", "Received message [" + message.SerialID + "]"
                                    , Niawa.Utilities.InlineSortedListCreator.CreateStrStr("NiawaNetMessage", message.ToJson())
                                    , _threadStatus.NodeID
                                    , _threadStatus.ParentNodeID);
                            }
                            receivingMessage = false;

                        }
                        catch (System.Threading.ThreadAbortException) // ex1)
                        {
                            //thread was aborted
                            if (receivingMessage == true)
                            {
                                logger.Error("[" + _description + "-T] Could not receive message: Thread aborted");

                                _evtRaiser.RaiseEvent("MessageError", "Cannot receive message - Thread aborted", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                                _threadStatus.MessageErrorCount += 1;
                            }
                            else
                            { logger.Debug("[" + _description + "-T] Thread aborted"); }
                            break;
                        }
                        catch (System.Threading.ThreadInterruptedException) // ex1)
                        {
                            //thread was interrupted
                            if (receivingMessage == true)
                            {
                                logger.Error("[" + _description + "-T] Could not receive message: Thread interrupted");

                                _evtRaiser.RaiseEvent("MessageError", "Cannot receive message - Thread interrupted", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                                _threadStatus.MessageErrorCount += 1;
                            }
                            else
                            { logger.Debug("[" + _description + "-T] Thread interrupted"); }
                            break;
                        }
                        catch (System.Net.Sockets.SocketException ex2)
                        {
                            //socket exception
                            if (ex2.Message.Contains("A blocking operation was interrupted by a call to WSACancelBlockingCall"))
                            {
                                if (receivingMessage == true)
                                {
                                    logger.Error("[" + _description + "-T] Could not receive message: Blocking operation interrupted");

                                    _evtRaiser.RaiseEvent("MessageError", "Cannot receive message - Blocking operation interrupted", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                                    _threadStatus.MessageErrorCount += 1;
                                }
                                else
                                { logger.Debug("[" + _description + "-T] Blocking operation interrupted"); }
                            }
                            else
                            {
                                if (receivingMessage == true)
                                {
                                    logger.Error("[" + _description + "-T] Could not receive message: Socket error [" + ex2.Message + "]", ex2);

                                    _evtRaiser.RaiseEvent("MessageError", "Cannot receive message - Socket error while receiving message: " + ex2.Message, null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                                    _threadStatus.MessageErrorCount += 1;
                                }
                                else
                                { logger.Debug("[" + _description + "-T] Socket error [" + ex2.Message + "]"); }
                            }

                        }
                        catch (Exception ex)
                        {
                            //exception
                            if (receivingMessage == true)
                            {
                                logger.Error("[" + _description + "-T] Could not receive message: Error [" + ex.Message + "]", ex);

                                _evtRaiser.RaiseEvent("Error", "Cannot receive message - Error while receiving message: " + ex.Message, null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                                _threadStatus.ErrorCount += 1;
                                _evtRaiser.RaiseEvent("MessageError", "Cannot receive message - Error while receiving message: " + ex.Message, null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                                _threadStatus.MessageErrorCount += 1;
                            }
                            else
                            { logger.Warn("[" + _description + "-T] Error while receiving messages [" + ex.Message + "]"); }

                            System.Threading.Thread.Sleep(100);
                        }

                        System.Threading.Thread.Sleep(10);

                    }
                }
                //done with ListenThread (stopped)

            }
            catch (Exception ex)
            {
                logger.Error("[" + _description + "-T] Error in listen thread: " + ex.Message, ex);
                _evtRaiser.RaiseEvent("Error", "[" + _description + "-T] Error in listen thread: " + ex.Message, null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                _threadStatus.ErrorCount += 1;
                throw ex;
            }
            finally
            {
                _threadStatus.IsThreadActive = false;
                _threadSuspended = false;
                _threadStatus.IsThreadEnabled = false;
                logger.Info("[" + _description + "-T] Receiver inactive");
            }
        }