/// <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; }
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(); } }