Ejemplo n.º 1
0
        /// <summary>
        /// Loop thread that watches handshake receiver message queue for new messages.  
        /// Dequeues messages, and looks for session initialization messages.  Other messages are discarded.
        /// </summary>
        /// <param name="data"></param>
        private void PollHandshakeReceiverThreadImpl(object data)
        {
            _t1_HR_ThreadStatus.IsThreadActive = true;
            logger.Info("[" + _description + "-THR] PollHandshakeReceiver active");

            while (_t1_HR_ThreadStatus.IsThreadEnabled)
            {
                try
                {
                    _t1_HR_ThreadStatus.ThreadHealthDate = DateTime.Now;

                    //check if there are any messages
                    if (_handshakeReceiver.CountMessagesInBuffer() > 0)
                    {
                        //dequeue message
                        NiawaNetMessage message = _handshakeReceiver.GetNextMessageFromBuffer();

                        _t1_HR_ThreadStatus.MessageCount += 1;

                        bool messageInvalidated = false;

                        //validate message destination hostname
                        if (message.DestinationHostname != _hostname)
                        {
                            //the message destination hostname doesn't match this hostname
                            logger.Warn("[" + _description + "-THR] PollHandshakeReceiver ignoring message [" + message.SerialID + "]; destination hostname [" + message.DestinationHostname + "] doesn't match the local hostname [" + _hostname + "]");
                            _evtRaiser_HR.RaiseEvent("Error", "PollHandshakeReceiver ignoring message [" + message.SerialID + "]; destination hostname [" + message.DestinationHostname + "] doesn't match the local hostname [" + _hostname + "]"
                                , Niawa.Utilities.InlineSortedListCreator.CreateStrStr("NiawaNetMessage", message.ToJson())
                                , _t1_HR_ThreadStatus.NodeID
                                , _t1_HR_ThreadStatus.ParentNodeID);
                            _t1_HR_ThreadStatus.MessageErrorCount += 1;

                            messageInvalidated = true;
                        }
                        //check for Session Initialization
                        if (message.MessageType != MessageContent.SessionInitMessageContent.MESSAGE_CONTENT_TYPE)
                        {
                            //not a session initialization

                            logger.Warn("[" + _description + "-THR] PollHandshakeReceiver ignoring message [" + message.SerialID + "]; unexpected message type [" + message.MessageType + "]");
                            _evtRaiser_HR.RaiseEvent("Error", "PollHandshakeReceiver ignoring message [" + message.SerialID + "]; unexpected message type [" + message.MessageType + "]"
                                , Niawa.Utilities.InlineSortedListCreator.CreateStrStr("NiawaNetMessage", message.ToJson())
                                , _t1_HR_ThreadStatus.NodeID
                                , _t1_HR_ThreadStatus.ParentNodeID);
                            _t1_HR_ThreadStatus.MessageErrorCount += 1;

                            messageInvalidated = true;
                        }

                        //check if message was invalidated
                        if (!messageInvalidated)
                        {

                            //message is valid

                            MessageContent.SessionInitMessageContent remoteSession = new MessageContent.SessionInitMessageContent(message.MessageContents);

                            logger.Info("[" + _description + "-THR] Received session initialization from [" + remoteSession.IpAddress + "]");
                            _evtRaiser_HR.RaiseEvent("Session", "Received session initialization from [" + remoteSession.IpAddress + "]", null, _t1_HR_ThreadStatus.NodeID, _t1_HR_ThreadStatus.ParentNodeID);

                            try
                            {
                                //find session
                                if (_tcpSessions.ContainsKey(remoteSession.IpAddress))
                                {
                                    /*we already have something relating to this session data*/
                                    /*we must have initiated this handshake;*/

                                    //  check if we've already received the session initialization
                                    TcpSession session = _tcpSessions[remoteSession.IpAddress];
                                    if (session.IsSessionInitReceived)
                                    {
                                        //we already received it, this message is in error
                                        logger.Error("[" + _description + "-THR] PollHandshakeReceiver ignoring session initialization message: the session [" + remoteSession.IpAddress + "] initialization has been previously received.");
                                        _evtRaiser_HR.RaiseEvent("SessionError", "PollHandshakeReceiver ignoring session initialization message: the session [" + remoteSession.IpAddress + "] initialization has been previously received."
                                            , Niawa.Utilities.InlineSortedListCreator.CreateStrStr("NiawaNetMessage", message.ToJson())
                                            , _t1_HR_ThreadStatus.NodeID
                                            , _t1_HR_ThreadStatus.ParentNodeID);
                                        _t1_HR_ThreadStatus.MessageErrorCount += 1;
                                    }
                                    else
                                    {
                                        //add the session init data
                                        ReceiveSessionInitialization(remoteSession);
                                    }

                                    //  check if we've already sent the session init
                                    if (session.IsSessionInitSent)
                                    {
                                        //nothing to do
                                        //it's expected that we already sent it, since we initiated this handshake
                                    }
                                    else
                                    {
                                        //for some reason it's not sent yet
                                        //log error
                                        logger.Error("[" + _description + "-THR] PollHandshakeReceiver error detected while receiving session initialization: the session [" + remoteSession.IpAddress + "] initialization has been received, but session initialization was never sent.");
                                        _evtRaiser_HR.RaiseEvent("SessionError", "PollHandshakeReceiver error detected while receiving session initialization: the session [" + remoteSession.IpAddress + "] initialization has been received, but session initialization was never sent."
                                            , Niawa.Utilities.InlineSortedListCreator.CreateStrStr("NiawaNetMessage", message.ToJson())
                                            , _t1_HR_ThreadStatus.NodeID
                                            , _t1_HR_ThreadStatus.ParentNodeID);
                                        _t1_HR_ThreadStatus.MessageErrorCount += 1;
                                    }

                                }
                                else
                                {
                                    /*we don't have anything relating to this sesion data yet*/
                                    /*the Remote must have initiated this handshake;*/

                                    //create a session with the remote session data, and then receive the session initialization from the remote
                                    MessageContent.SessionInitMessageContent localSession = CreateNewSession(remoteSession);

                                    //transmit session initialization to the remote
                                    TransmitSessionInitialization(remoteSession.IpAddress, remoteSession.HandshakePort, remoteSession.Hostname, localSession);
                                }
                            }
                            finally
                            {
                            }

                        }
                        else
                        {
                            //message is not valid

                            logger.Info("[" + _description + "-THR] Message was ignored");
                        }
                    }
                    else
                    {
                        //there are no messages
                    }
                }
                catch (System.Threading.ThreadAbortException) // ex1)
                {
                    //thread was aborted
                    logger.Debug("[" + _description + "-THR] Thread aborted");
                    break;
                }
                catch (System.Threading.ThreadInterruptedException) // ex1)
                {
                    //thread was interrupted
                    logger.Debug("[" + _description + "-THR] Thread interrupted");
                    break;
                }
                catch (Exception ex)
                {
                    //exception
                    logger.Error("[" + _description + "-THR] Error while polling handshake receiver: " + ex.Message + "]", ex);
                    //ipcLoggerMsg.Write("ReceiveMessageError", "[" + _logInstanceName + "]: " + "Error: " + ex.Message);
                    _evtRaiser_HR.RaiseEvent("Error", "Error while polling handshake receiver [" + ex.Message + "]", null, _t1_HR_ThreadStatus.NodeID, _t1_HR_ThreadStatus.ParentNodeID);
                    _t1_HR_ThreadStatus.ErrorCount += 1;
                    System.Threading.Thread.Sleep(100);
                }

                System.Threading.Thread.Sleep(50);

            }
            //done working
            _t1_HR_ThreadStatus.IsThreadActive = false;

            //thread status
            _t1_HR_ThreadStatus.Status = Niawa.Threading.ThreadStatus.STATUS_STOPPED;
        }
Ejemplo n.º 2
0
        private MessageContent.SessionInitMessageContent CreateNewSession_Internal(string remoteIpAddress, string remoteHostname, int remoteHandshakePort)
        {
            //attempt lock
            bool tryLock = lockSection.WaitOne(60000);
            if (!tryLock) throw new TimeoutException("[" + _description + "-M] Could not obtain lock while creating new session]");

            try
            {
                //check if session already exists
                if (_tcpSessions.ContainsKey(remoteIpAddress))
                {
                    _evtRaiser.RaiseEvent("SessionError", "Cannot create session:  A session already exists for address [" + remoteIpAddress + "]", null, _t2_SRL_ThreadStatus.NodeID, _t2_SRL_ThreadStatus.ParentNodeID);
                    throw new Exception("[" + _description + "-M] Cannot create session:  A session already exists for address [" + remoteIpAddress + "]");
                }

                //create a new session
                TcpSession session = new TcpSession(_applicationName, _ipAddress, _portRangeMin, _portRangeMax, remoteIpAddress, remoteHostname, remoteHandshakePort, _evtConsumer, _utilsBus,_t2_SRL_ThreadStatus.NodeID);

                //start the receiver
                session.ReceiverStart(_applicationName + ".TcpSessionManager.CreateNewSession");

                /*the session is now half-created*/
                /*the remote session data will be added later when the remote makes it available*/

                //get the port and return the ip and port info
                MessageContent.SessionInitMessageContent initMessage = new MessageContent.SessionInitMessageContent(_ipAddress, _hostname, _handshakePort, session.LocalPort);
                //initMessage.IpAddress = _ipAddress;
                //initMessage.Hostname = _hostname;
                //initMessage.HandshakePort = _handshakePort;
                //initMessage.SessionPort = session.LocalPort;

                //add session to the session list
                _tcpSessions.Add(remoteIpAddress, session);

                //return session initialization object
                return initMessage;
            }
            finally
            {
                //release lock
                lockSection.Release();
            }
        }