Exemplo n.º 1
0
        // 1 回の処理
        async Task <int> PerformOnceAsync(CancellationToken cancel = default)
        {
            CoresRuntimeStat runtimeStat = new CoresRuntimeStat();

            runtimeStat.Refresh(forceGc: this.Report_ForceGc);

            string[]? globalIpList = null;

            try
            {
                globalIpList = (await LocalNet.GetLocalHostPossibleIpAddressListAsync(cancel)).Select(x => x.ToString()).ToArray();
            }
            catch { }

            InstanceStat stat = new InstanceStat
            {
                DaemonName           = this.Settings.DaemonName,
                CommitId             = this.Variables.CurrentCommitId,
                CommitInfo           = this.Variables.CurrentCommitInfo,
                InstanceArguments    = this.Variables.CurrentInstanceArguments,
                RuntimeStat          = runtimeStat,
                EnvInfo              = new EnvInfoSnapshot(),
                StatFlag             = this.Variables.StatFlag,
                TcpIpHostData        = LocalNet.GetTcpIpHostDataJsonSafe(true),
                GlobalIpList         = globalIpList,
                PauseFlag            = Variables.PauseFlag,
                MetaStatusDictionary = GlobalDaemonStateManager.MetaStatusDictionary,
                DaemonSecret         = GlobalDaemonStateManager.DaemonSecret,
            };

            // リクエストメッセージの組立て
            RequestMsg req = new RequestMsg
            {
                AppId    = this.Settings.AppId,
                HostName = this.Settings.HostName,
                Guid     = this.Settings.HostGuid,
                Stat     = stat,
            };

            // サーバーに送付し応答を受信
            ResponseMsg res = await Rpc.KeepAliveAsync(req);

            // 応答メッセージの分析
            res.Normalize();

            // ローカル IP アドレスを覚える
            GlobalDaemonStateManager.SetDaemonClientLocalIpAddress(RpcClient.LastLocalIp);

            // FileBrowser の URL が分かればこれを DaemonCenter に送付する
            if (GlobalDaemonStateManager.FileBrowserHttpsPortNumber != 0)
            {
                IPAddress ip       = GlobalDaemonStateManager.DaemonClientLocalIpAddress;
                string    hostname = ip.ToString();

                if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                {
                    // ipv6
                    hostname = $"[{hostname}]";
                }

                try
                {
                    // FQDN を DNS 解決する
                    string?fqdn = req.Stat.TcpIpHostData.FqdnHostName;

                    if (fqdn._IsFilled())
                    {
                        DnsResponse dnsReply = await LocalNet.QueryDnsAsync(new DnsGetIpQueryParam(fqdn, timeout : Consts.Timeouts.Rapid), cancel);

                        if (dnsReply.IPAddressList.Where(x => x == ip).Any())
                        {
                            // DNS 解決に成功し、同一の IP アドレスを指していることが分かったので URL には FQDN を埋め込む
                            hostname = fqdn;
                        }
                    }
                }
                catch { }

                // url
                string url = $"https://{hostname}:{GlobalDaemonStateManager.FileBrowserHttpsPortNumber}/{GlobalDaemonStateManager.DaemonSecret}/";

                GlobalDaemonStateManager.MetaStatusDictionary[Consts.DaemonMetaStatKeys.CurrentLogFileBrowserUrl] = url;
            }
            else
            {
                GlobalDaemonStateManager.MetaStatusDictionary.TryRemove(Consts.DaemonMetaStatKeys.CurrentLogFileBrowserUrl, out _);
            }

            if (res.OsRebootRequested)
            {
                // OS そのものの再起動が要求されたので再起動を行なう
                if (Env.IsAdmin)
                {
                    try
                    {
                        Kernel.RebootOperatingSystemForcefullyDangerous();
                    }
                    catch { }
                }
            }

            if (res.NextCommitId._IsFilled() || res.NextInstanceArguments._IsFilled() || res.NextPauseFlag != PauseFlag.None || res.RebootRequested)
            {
                // 再起動が要求された
                this.RestartCb(res);

                return(-1);
            }

            // 次回 KeepAlive 間隔の応答
            return(res.NextKeepAliveMsec);
        }