/// <summary> /// Executes the reverse client loop. /// </summary> private void ReverseClientExecute() { reverseClient = new ReverseClient(reverseConnectionOptions); while (!reverseClientTerminated) { try { // reconnect reverse client if (reverseClient.ClientState != ClientState.LoggedIn && reverseClient.ConnectionAllowed) { if (reverseClient.RestoreConnection(out string errMsg)) { if (CreateSession(reverseClient.SessionID, out ConnectedClient client)) { Thread clientThread = new Thread(ClientExecute); client.Init(reverseClient.TcpClient, clientThread); client.IsLoggedIn = true; client.Username = reverseConnectionOptions.Username; client.UserID = reverseClient.UserID; client.RoleID = reverseClient.RoleID; coreLogic.GetInstance(reverseConnectionOptions.Instance, out ScadaInstance instance); client.Tag = new ClientTag(true) { Instance = instance }; log.WriteAction(Locale.IsRussian ? "Обратный клиент подключился к {0}" : "Reverse client connected to {0}", client.Address); clientThread.Start(client); } } else if (!string.IsNullOrEmpty(errMsg)) { log.WriteError(errMsg); } } } catch (Exception ex) { log.WriteError(ex, Locale.IsRussian ? "Ошибка в цикле обратного клиента" : "Error in the reverse client loop"); } finally { Thread.Sleep(ScadaUtils.ThreadDelay); } } }
private DateTime heartbeatDT; // the last time a heartbeat was sent to remote Agents /// <summary> /// Initializes a new instance of the class. /// </summary> public AgentListener(CoreLogic coreLogic, ListenerOptions listenerOptions, ReverseConnectionOptions reverseConnectionOptions) : base(listenerOptions, coreLogic.Log) { this.coreLogic = coreLogic ?? throw new ArgumentNullException(nameof(coreLogic)); this.reverseConnectionOptions = reverseConnectionOptions ?? throw new ArgumentNullException(nameof(reverseConnectionOptions)); clientBundles = new Dictionary <string, ClientBundle>(); reverseClient = null; reverseClientThread = null; reverseClientTerminated = false; heartbeatDT = DateTime.MinValue; CustomFunctions = new HashSet <int> { FunctionID.DownloadFile, FunctionID.UploadFile }; }