/// <summary> /// Loop thread that processes messages received from UDP receiver. /// </summary> /// <param name="data"></param> private void UdpReceiverListenerThreadImpl(object data) { _threadStatus.IsThreadActive = true; logger.Info("[" + _description + "-T] UdpReceiverListener active"); while (_threadStatus.IsThreadEnabled) { try { _threadStatus.ThreadHealthDate = DateTime.Now; //check if there are any messages if (_udpReceiver.CountMessagesInBuffer() > 0) { //dequeue message NiawaNetDatagram message = _udpReceiver.GetNextMessageFromBuffer(); /*when receive UDP handshake, pass session data to TCP session manager*/ //check for handshake message if (message.MessageType == MessageContent.HandshakeMessageContent.MESSAGE_CONTENT_TYPE) { //handshake message MessageContent.HandshakeMessageContent remoteServerData = new MessageContent.HandshakeMessageContent(message.MessageContents); logger.Info("[" + _description + "-T] Received handshake message from [" + remoteServerData.IpAddress + "]"); _evtRaiser.RaiseEvent("Session", "Received handshake message from [" + remoteServerData.IpAddress + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); //find session if (_tcpSessionManager.TcpSessions.ContainsKey(remoteServerData.IpAddress)) { //we already have something relating to this session data logger.Warn("[" + _description + "-T] UdpReceiverListener received a handshake message for existing session [" + remoteServerData.IpAddress + "]"); //check if any of the information has changed TcpSession existingSession = _tcpSessionManager.TcpSessions[remoteServerData.IpAddress]; bool invalidateSession = false; //check this existing session for any reasons that would invalidate the session invalidateSession = ReceivedHandshakeExistingSessionValidations(existingSession, remoteServerData); if (invalidateSession) { //invalidate session and create new one logger.Info("[" + _description + "-T] UdpReceiverListener removing invalidated session before creating a new session for [" + remoteServerData.IpAddress + "]"); _evtRaiser.RaiseEvent("Session", "Removing invalidated session before creating a new session for [" + remoteServerData.IpAddress + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); //remove old session _tcpSessionManager.RemoveSession(remoteServerData.IpAddress, false); //create a session with the remote session data, and then receive the session initialization from the remote MessageContent.SessionInitMessageContent localSession = _tcpSessionManager.CreateNewSession(remoteServerData.IpAddress, remoteServerData.Hostname, remoteServerData.HandshakePort); //transmit session initialization to the remote _tcpSessionManager.TransmitSessionInitialization(remoteServerData.IpAddress, remoteServerData.HandshakePort, remoteServerData.Hostname, localSession); } else { //existing session is still valid; don't do anything logger.Info("[" + _description + "-T] UdpReceiverListener ignoring handshake message for existing session [" + remoteServerData.IpAddress + "]"); _evtRaiser.RaiseEvent("Session", "Ignoring handshake message for existing session [" + remoteServerData.IpAddress + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); } } else { /*we don't have anything relating to this sesion data yet*/ //create a session with the remote session data, and then receive the session initialization from the remote MessageContent.SessionInitMessageContent localSession = _tcpSessionManager.CreateNewSession(remoteServerData.IpAddress, remoteServerData.Hostname, remoteServerData.HandshakePort); //transmit session initialization to the remote _tcpSessionManager.TransmitSessionInitialization(remoteServerData.IpAddress, remoteServerData.HandshakePort, remoteServerData.Hostname, localSession); } } else if (message.MessageType == MessageContent.PingMessageContent.MESSAGE_CONTENT_TYPE_PING) { //ping message MessageContent.PingMessageContent pingData = new MessageContent.PingMessageContent(message.MessageContents); logger.Info("[" + _description + "-T] Received ping message from [" + pingData.IpAddress + "]"); _evtRaiser.RaiseEvent("Message", "Received ping message from [" + pingData.IpAddress + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); //send a reply TransmitPingMessage(true, message.SerialID.ToString()); } else if (message.MessageType == MessageContent.PingMessageContent.MESSAGE_CONTENT_TYPE_PINGREPLY) { //ping message MessageContent.PingMessageContent pingData = new MessageContent.PingMessageContent(message.MessageContents); logger.Info("[" + _description + "-T] Received ping reply message from [" + pingData.IpAddress + "] for ping SerialID [" + pingData.ReplySerialID + "]"); _evtRaiser.RaiseEvent("Message", "Received ping reply from [" + pingData.IpAddress + "] for ping SerialID [" + pingData.ReplySerialID + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); } else { //message is not valid - not a handshake message //throw away other data logger.Warn("[" + _description + "-T] UdpReceiverListener ignoring unexpected message type [" + message.MessageType + "]"); _evtRaiser.RaiseEvent("Error", "UdpReceiverListener: Ignoring unexpected message type [" + message.MessageType + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); } } else { //there are no messages } } catch (System.Threading.ThreadAbortException) // ex1) { //thread was aborted logger.Debug("[" + _description + "-T] Thread aborted"); break; } catch (System.Threading.ThreadInterruptedException) // ex1) { //thread was interrupted logger.Debug("[" + _description + "-T] Thread interrupted"); break; } catch (Exception ex) { //exception logger.Error("[" + _description + "-T] Error while listening to UdpReceiver: " + ex.Message + "]", ex); //ipcLoggerMsg.Write("ReceiveMessageError", "[" + _logInstanceName + "]: " + "Error: " + ex.Message); _evtRaiser.RaiseEvent("Error", "Error while listening to UdpReceiver [" + ex.Message + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID); _threadStatus.ErrorCount += 1; System.Threading.Thread.Sleep(100); } System.Threading.Thread.Sleep(50); } //done working _threadStatus.IsThreadActive = false; }
/// <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; } }