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