static void Main(string[] args) { HomePath.SetHomeDirFullName(AppDomain.CurrentDomain.BaseDirectory); if (args.Length != 0) { if (args.Contains("--sha1")) { File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sha1"), Sha1); return; } } try { if (DevMode.IsDevMode) { NTMinerConsole.GetOrAlloc(); } SystemEvents.SessionEnding += SessionEndingEventHandler; StartTimer(); _waitHandle = new AutoResetEvent(false); bool mutexCreated; try { _sMutexApp = new Mutex(true, "NTMinerNoDevFeeAppMutex", out mutexCreated); } catch { mutexCreated = false; } if (mutexCreated) { if (!DevMode.IsDevMode) { Write.Disable(); } NTMinerRegistry.SetNoDevFeeVersion(Sha1); NTMinerRegistry.SetAutoBoot("NTMinerNoDevFee", true); Run(); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }
// 从磁盘读取local.json反序列化为LocalJson对象 private static void LocalJsonInit() { if (!_localJsonInited) { lock (_locker) { if (!_localJsonInited) { string localJson = HomePath.ReadLocalJsonFile(_workType); LocalJsonDb localJsonDb = null; if (!string.IsNullOrEmpty(localJson)) { localJsonDb = VirtualRoot.JsonSerializer.Deserialize <LocalJsonDb>(localJson); } if (localJsonDb == null) { if (ClientAppType.IsMinerClient) { localJsonDb = JsonDb.LocalJsonDb.ConvertFromNTMinerContext(); VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), "当前作业由本机数据自动生成,因为本机没有作业记录,请先在群控端创建或编辑作业。", OutEnum.Warn, toConsole: true); } else { localJsonDb = new LocalJsonDb(); } } _localJsonDb = localJsonDb; if (ClientAppType.IsMinerClient) { #region 因为是群控作业,将开机启动和自动挖矿设置为true var repository = new LiteDbReadWriteRepository <MinerProfileData>(HomePath.LocalDbFileFullName); MinerProfileData localProfile = repository.GetByKey(MinerProfileData.DefaultId); if (localProfile != null) { MinerProfileData.CopyWorkIgnoreValues(localProfile, _localJsonDb.MinerProfile); // 如果是作业模式则必须设置为开机自动重启 if (!localProfile.IsAutoBoot) { localProfile.IsAutoBoot = true; repository.Update(localProfile); } } _localJsonDb.MinerProfile.IsAutoBoot = true; NTMinerRegistry.SetIsAutoStart(true); #endregion #region 矿机名 if (!string.IsNullOrEmpty(_workerName)) { _localJsonDb.MinerProfile.MinerName = _workerName; } else { // 当用户使用群控作业但没有指定群控矿机名时使用从local.litedb中读取的矿工名 if (string.IsNullOrEmpty(_localJsonDb.MinerProfile.MinerName)) { if (localProfile != null) { _localJsonDb.MinerProfile.MinerName = localProfile.MinerName; } // 如果local.litedb中也没有矿机名则使用去除了特殊符号的本机机器名作为矿机名 if (string.IsNullOrEmpty(_localJsonDb.MinerProfile.MinerName)) { _localJsonDb.MinerProfile.MinerName = NTKeyword.GetSafeMinerName(ThisPcName); } } } #endregion } _localJsonInited = true; } } } }
public void Init(Action callback) { Task.Factory.StartNew(() => { bool isSelfWork = Environment.GetCommandLineArgs().Contains("--selfWork", StringComparer.OrdinalIgnoreCase); bool isWork = isSelfWork || Environment.GetCommandLineArgs().Contains("--work", StringComparer.OrdinalIgnoreCase); _workType = isSelfWork ? WorkType.SelfWork : (isWork ? WorkType.MineWork : WorkType.None); if (ClientAppType.IsMinerClient) { NTMinerRegistry.SetWorkType(_workType); } if (isWork) { DoInit(callback); } else { // 如果是Debug模式且不是群控客户端则使用本地数据库初始化 bool useLocalDb = DevMode.IsDevMode && !ClientAppType.IsMinerStudio; if (useLocalDb) { DoInit(callback); } else { Logger.InfoDebugLine(nameof(RpcRoot.OSSService.AliyunOSSService.GetAliyunServerJson)); RpcRoot.OSSService.AliyunOSSService.GetAliyunServerJson((data) => { // 如果server.json未下载成功则不覆写本地server.json if (data != null && data.Length != 0) { Logger.InfoDebugLine($"{nameof(RpcRoot.OSSService.AliyunOSSService.GetAliyunServerJson)} ok"); var serverJson = Encoding.UTF8.GetString(data); if (!string.IsNullOrEmpty(serverJson)) { HomePath.WriteServerJsonFile(serverJson); } RpcRoot.OfficialServer.AppSettingService.GetJsonFileVersionAsync(ClientAppType.AppType, HomePath.ExportServerJsonFileName, serverState => { SetServerJsonVersion(serverState.JsonFileVersion); AppVersionChangedEvent.PublishIfNewVersion(serverState.MinerClientVersion); if (serverState.Time == 0) { NTMinerConsole.UserWarn("网络不通或服务器暂时不可用,请检查矿机网络"); } else if (Math.Abs((long)Timestamp.GetTimestamp() - (long)serverState.Time) >= Timestamp.DesyncSeconds) { NTMinerConsole.UserWarn($"本机和服务器时间不同步,请调整,本地:{DateTime.Now.ToString()},服务器:{Timestamp.FromTimestamp(serverState.Time).ToString()}。此问题不影响挖矿。"); } }); } else { if (!File.Exists(HomePath.ServerJsonFileFullName)) { VirtualRoot.ThisLocalError(nameof(NTMinerContext), "配置文件下载失败,这是第一次运行开源矿工,配置文件至少需要成功下载一次,请检查网络是否可用", OutEnum.Warn); } else { VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), "配置文件下载失败,使用最近一次成功下载的配置文件"); } } DoInit(callback); }); } } VirtualRoot.ThisLocalInfo(nameof(NTMinerContext), $"启动{VirtualRoot.AppName}"); }); }
static void Main() { NTMinerConsole.DisbleQuickEditMode(); HomePath.SetHomeDirFullName(AppDomain.CurrentDomain.BaseDirectory); try { bool mutexCreated; try { // 锁名称上带上本节点的端口号,从而允许一个服务器上运行多个WebApiServer节点,这在软升级服务端程序时有用。 // 升级WebApiServer程序的时候步骤是: // 1,在另一个端口启动新版本的程序; // 2,让Widnows将来自旧端口的所有tcp请求转发到新端口; // 3,退出旧版本的程序并更新到新版本; // 4,删除第2步添加的Windows的端口转发; // 5,退出第1步运行的节点; // TODO:实现软升级策略 _sMutexApp = new Mutex(true, $"NTMinerServicesMutex{ServerRoot.HostConfig.GetServerPort().ToString()}", out mutexCreated); } catch { mutexCreated = false; } if (mutexCreated) { try { // 用本节点的地址作为队列名,消费消息时根据路由键区分消息类型 string queue = $"{ServerAppType.WebApiServer.GetName()}.{ServerRoot.HostConfig.ThisServerAddress}"; string durableQueue = queue + MqKeyword.DurableQueueEndsWith; AbstractMqMessagePath[] mqMessagePaths = new AbstractMqMessagePath[] { new UserMqMessagePath(durableQueue), new MinerClientMqMessagePath(queue) }; _serverContext = ServerContext.Create(mqClientTypeName: ServerAppType.WebApiServer.GetName(), mqMessagePaths); if (_serverContext == null) { Write.UserError("启动失败,无法继续,因为服务器上下文创建失败"); return; } Console.Title = $"{ServerAppType.WebApiServer.GetName()}_{ServerRoot.HostConfig.ThisServerAddress}"; _ossClient = new OssClient(ServerRoot.HostConfig.OssEndpoint, ServerRoot.HostConfig.OssAccessKeyId, ServerRoot.HostConfig.OssAccessKeySecret); var minerClientMqSender = new MinerClientMqSender(_serverContext.Channel); var userMqSender = new UserMqSender(_serverContext.Channel); var wsServerNodeMqSender = new WsServerNodeMqSender(_serverContext.Channel); var minerRedis = new MinerRedis(_serverContext.RedisConn); var speedDataRedis = new SpeedDataRedis(_serverContext.RedisConn); var userRedis = new UserRedis(_serverContext.RedisConn); var captchaRedis = new CaptchaRedis(_serverContext.RedisConn); WsServerNodeSet = new WsServerNodeSet(wsServerNodeMqSender); UserSet = new UserSet(userRedis, userMqSender); UserAppSettingSet = new UserAppSettingSet(); CaptchaSet = new CaptchaSet(captchaRedis); CalcConfigSet = new CalcConfigSet(); NTMinerWalletSet = new NTMinerWalletSet(); ClientDataSet clientDataSet = new ClientDataSet(minerRedis, speedDataRedis, minerClientMqSender); ClientDataSet = clientDataSet; CoinSnapshotSet = new CoinSnapshotSet(clientDataSet); MineWorkSet = new UserMineWorkSet(); MinerGroupSet = new UserMinerGroupSet(); NTMinerFileSet = new NTMinerFileSet(); OverClockDataSet = new OverClockDataSet(); KernelOutputKeywordSet = new KernelOutputKeywordSet(SpecialPath.LocalDbFileFullName, isServer: true); ServerMessageSet = new ServerMessageSet(SpecialPath.LocalDbFileFullName, isServer: true); UpdateServerMessageTimestamp(); if (VirtualRoot.LocalAppSettingSet.TryGetAppSetting(nameof(KernelOutputKeywordTimestamp), out IAppSetting appSetting) && appSetting.Value is DateTime value) { KernelOutputKeywordTimestamp = value; } else { KernelOutputKeywordTimestamp = Timestamp.UnixBaseTime; } } catch (Exception e) { Write.UserError(e.Message); Write.UserError(e.StackTrace); Write.UserInfo("按任意键退出"); Console.ReadKey(); return; } VirtualRoot.StartTimer(); NTMinerRegistry.SetAutoBoot("NTMinerServices", true); Type thisType = typeof(WebApiRoot); Run(); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }
public void Init(Action callback) { Task.Factory.StartNew(() => { bool isWork = Environment.GetCommandLineArgs().Contains("--work", StringComparer.OrdinalIgnoreCase); if (isWork) // 是作业 { DoInit(isWork, callback); if (ClientAppType.IsMinerClient) { NTMinerRegistry.SetIsLastIsWork(true); } } else // 不是作业 { if (ClientAppType.IsMinerClient) { NTMinerRegistry.SetIsLastIsWork(false); } // 如果是Debug模式且不是群控客户端则使用本地数据库初始化 bool useLocalDb = DevMode.IsDevMode && !ClientAppType.IsMinerStudio; if (useLocalDb) { DoInit(isWork: false, callback: callback); } else { Logger.InfoDebugLine(nameof(GetAliyunServerJson)); GetAliyunServerJson((data) => { // 如果server.json未下载成功则不覆写本地server.json if (data != null && data.Length != 0) { Logger.InfoDebugLine($"{nameof(GetAliyunServerJson)}成功"); var serverJson = Encoding.UTF8.GetString(data); if (!string.IsNullOrEmpty(serverJson)) { HomePath.WriteServerJsonFile(serverJson); } RpcRoot.OfficialServer.AppSettingService.GetJsonFileVersionAsync(HomePath.ExportServerJsonFileName, serverState => { SetServerJsonVersion(serverState.JsonFileVersion); AppVersionChangedEvent.PublishIfNewVersion(serverState.MinerClientVersion); if (Math.Abs((long)Timestamp.GetTimestamp() - (long)serverState.Time) >= Timestamp.DesyncSeconds) { Write.UserWarn($"本机和服务器时间不同步,请调整,本地:{DateTime.Now.ToString()},服务器:{Timestamp.FromTimestamp(serverState.Time).ToString()}。此问题不影响挖矿。"); } }); } else { if (!File.Exists(HomePath.ServerJsonFileFullName)) { VirtualRoot.ThisLocalError(nameof(NTMinerContext), "配置文件下载失败,这是第一次运行开源矿工,配置文件至少需要成功下载一次,请检查网络是否可用", OutEnum.Warn); } else { VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), "配置文件下载失败,使用最近一次成功下载的配置文件"); } } DoInit(isWork, callback); }); #region 发生了用户活动时检查serverJson是否有新版本 VirtualRoot.AddEventPath <UserActionEvent>("发生了用户活动时检查serverJson是否有新版本", LogEnum.DevConsole, action: message => { RefreshServerJsonFile(); }, location: this.GetType()); #endregion } } VirtualRoot.ThisLocalInfo(nameof(NTMinerContext), $"启动{VirtualRoot.AppName}"); }); }
static void Main(string[] args) { HomePath.SetHomeDirFullName(AppDomain.CurrentDomain.BaseDirectory); SetOut(new ConsoleOut()); if (args.Length != 0) { if (args.Contains("--sha1")) { File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sha1"), Sha1); return; } } try { SystemEvents.SessionEnding += SessionEndingEventHandler; StartTimer(); _waitHandle = new AutoResetEvent(false); bool mutexCreated; try { _sMutexApp = new Mutex(true, "NTMinerDaemonAppMutex", out mutexCreated); } catch { mutexCreated = false; } if (mutexCreated) { if (!DevMode.IsDevMode) { Write.Disable(); } NTMinerRegistry.SetDaemonVersion(Sha1); NTMinerRegistry.SetAutoBoot("NTMinerDaemon", true); #region 是否自动启动挖矿端 bool isAutoBoot = MinerProfileUtil.GetIsAutoBoot(); if (isAutoBoot) { string location = NTMinerRegistry.GetLocation(NTMinerAppType.MinerClient); if (!string.IsNullOrEmpty(location) && File.Exists(location)) { string processName = Path.GetFileName(location); Process[] processes = Process.GetProcessesByName(processName); if (processes.Length == 0) { string arguments = NTMinerRegistry.GetArguments(NTMinerAppType.MinerClient); if (NTMinerRegistry.GetIsLastIsWork()) { arguments = "--work " + arguments; } try { Process.Start(location, arguments); Write.DevOk(() => $"启动挖矿端 {location} {arguments}"); } catch (Exception e) { Logger.ErrorDebugLine($"启动挖矿端失败因为异常 {location} {arguments}", e); } } else { Write.DevDebug($"挖矿端已经在运行中无需启动"); } } } #endregion Run(); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }