private void sinkHeartBeatTimer(long NOTUSED) { try { TheDiagnostics.SetThreadName("HeartbeatTimer", true); mHeartBeatTicker++; TheBaseAssets.MySYSLOG.WriteToLog(2803, TSM.L(eDEBUG_LEVELS.EVERYTHING) ? null : new TSM("QSender", $"Enter HearbeatTimer for ORG:{MyTargetNodeChannel}", eMsgLevel.l7_HostDebugMessage)); TheTimeouts tTO = TheBaseAssets.MyServiceHostInfo.TO; if (!IsHeartBeatAlive(tTO.DeviceCleanSweepTimeout * 2) && TheCommonUtils.IsDeviceSenderType(MyTargetNodeChannel?.SenderType ?? cdeSenderType.NOTSET) && MyTargetNodeChannel?.IsWebSocket == false) //IDST-OK: Remove dead devices that might have hard disconnected (no correct disconnect) i.e. http browsers were just closed { TheBaseAssets.MySYSLOG.WriteToLog(2820, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("QSender", $"Forced Removal of QSender {MyTargetNodeChannel.ToMLString()} due to DeviceCleanSweep", eMsgLevel.l4_Message)); Guid?tTarget = MyTargetNodeChannel?.cdeMID; DisposeSender(true); if (tTarget.HasValue) { TheQueuedSenderRegistry.RemoveOrphan(tTarget.Value); TheCommCore.PublishCentral(new TSM(eEngineName.ContentService, "CDE_DELETEORPHAN", tTarget.ToString())); } return; } if (!IsAlive && !MyTargetNodeChannel?.IsWebSocket == true) { return; //NEW:V3 2013/12/13 allow for cloud reconnect if WebSockets } if ((mHeartBeatTicker % (tTO.HeartBeatRate * 2)) == 0) { if (MyTargetNodeChannel?.SenderType != cdeSenderType.CDE_LOCALHOST) { timerMyHeartbeatTimer(); } if (MyTargetNodeChannel?.SenderType == cdeSenderType.CDE_CLOUDROUTE && ((!IsConnected && !IsConnecting) || !IsAlive) && (mHeartBeatTicker % (tTO.HeartBeatRate * 10)) == 0) //tQ.MyTargetNodeChannel.IsWebSocket && NOW ALWAYS RECONNECT { TheCommonUtils.cdeRunAsync("ReconnectCloud", true, (o) => ReconnectCloud()); } if (MyTargetNodeChannel?.SenderType != cdeSenderType.CDE_LOCALHOST && IsAlive && IsConnected) //!TheBaseAssets.MyServiceHostInfo.IsCloudService && !tQ.MyTargetNodeChannel.IsWebSocket && { if (MyTargetNodeChannel?.IsWebSocket != true) { if (GetQueLength() == 0) { TheBaseAssets.MyServiceHostInfo.TO.MakeHeartPump(); // CODE REVIEW Markus: Isn't this backwards: we should pump faster while we have more work to do? SendPickupMessage(); //Pickup } else { TheBaseAssets.MyServiceHostInfo.TO.MakeHeartNormal(); } } else { SendPickupMessage(); //Pickup } } } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(2821, new TSM("QSRegistry", $"Fatal Error in HealthTimer for QS:{this.cdeMID} and MTNC:{MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l1_Error, e.ToString())); } }
internal static bool ParseSimplex(string pScopedTopic, TSM pMessage, TheQueuedSender pQSender) //, TheSessionState pSessionState, Action<TSM> pLocalCallback) { if (pMessage == null) { return(false); } #if !JC_COMMDEBUG try { #endif if (pMessage?.TXT?.Equals("CDE_DELETEORPHAN") == true) { TheQueuedSenderRegistry.RemoveOrphan(TheCommonUtils.CGuid(pMessage.PLS)); return(false); } if (pQSender == null) { TheBaseAssets.MySYSLOG.WriteToLog(291, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", $"QSender not found! Received from ORG:{TheCommonUtils.GetDeviceIDML(pMessage?.ORG)}", eMsgLevel.l1_Error, pMessage?.PLS)); return(false); } //SECURITY-REVIEW: This cannot be permitted without extra tokens and Encryption! otherwise it can be used to change a nodes scope on the fly! //if ("CDE_UPDATESCOPE".Equals(pMessage.TXT)) //{ // pQSender.UpdateSubscriptionScope(TheBaseAssets.MyScopeManager.GetRealScopeID(pMessage.SID)); //GRSI: rare // return true; //} if (pQSender != null && pMessage.ENG?.StartsWith(eEngineName.ContentService) == true && pMessage?.TXT == "CDE_SERVICE_INFO" && pQSender.MyTargetNodeChannel?.RealScopeID == TheBaseAssets.MyScopeManager.GetRealScopeID(pMessage.SID)) { try { pQSender.SetNodeInfo(TheCommonUtils.DeserializeJSONStringToObject <TheNodeInfoClone>(pMessage?.PLS)); } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(23056, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"Error decoding SystemInfo {pQSender?.MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l1_Error, e.ToString())); } } if (pMessage.TXT?.Equals("CDE_SUBSCRIBE") == true || pMessage.TXT?.Equals("CDE_INITIALIZE") == true) //9-9-2012 CDEC Did not work right on CDE_INIT { TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"Parse-Simplex Subscribe from {pQSender?.MyTargetNodeChannel?.ToMLString()} Parsed: {pMessage?.PLS}", eMsgLevel.l7_HostDebugMessage)); if (pQSender?.MyISBlock != null && !TheBaseAssets.MyServiceHostInfo.IsCloudService) { TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", "Parse-Simplex Subscribe rejected for Custom ISBConnect", eMsgLevel.l7_HostDebugMessage)); return(true); } ParseSubscribe(pMessage.PLS, pQSender); if (pMessage.ENG.Equals("CLOUDSYNC")) { string[] tTopics = pMessage.PLS.Split(';'); foreach (string t in tTopics) { TSM.GetScrambledIDFromTopic(t, out string tEng); if (TheThingRegistry.IsEngineRegistered(tEng)) { IBaseEngine tsBase = TheThingRegistry.GetBaseEngine(tEng); tsBase?.GetBaseThing()?.FireEvent(eEngineEvents.NewSubscription, tsBase.GetBaseThing(), pQSender.MyTargetNodeChannel, true); } } return(true); } else { TheThing tBase2 = TheThingRegistry.GetBaseEngineAsThing(pMessage.ENG); if (tBase2 != null) { tBase2.FireEvent(eEngineEvents.NewSubscription, tBase2, pQSender.MyTargetNodeChannel, true); } } if (pMessage.TXT.Equals("CDE_SUBSCRIBE")) //NEW:2.06 Make sure Subscribe and Unsubscribe only go to first node { return(true); } else { return(false); } } if (pMessage.TXT?.Equals("CDE_UNSUBSCRIBE") == true) { TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"Parse-Simplex Unsubscribe from {pQSender.MyTargetNodeChannel?.ToMLString()} Parsed: {pMessage.PLS}", eMsgLevel.l7_HostDebugMessage)); ParseUnsubscribe(pMessage.PLS, pQSender); return(true); //NEW:2.06 Make sure Subscribe and Unsubscribe only go to first node } #if !JC_COMMDEBUG } catch (Exception ee) { TheBaseAssets.MySYSLOG.WriteToLog(316, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", "Parse-Simplex", eMsgLevel.l1_Error, ee.ToString())); } #endif return(false); }