static void Main() { using (var ws = new WebSocket("ws://localhost:8088/")) { ws.OnOpen += (sender, e) => { Write.UserWarn($"WebSocket Open"); ws.Send("Hi!"); }; ws.OnMessage += (sender, e) => { if (string.IsNullOrEmpty(e.Data) || e.Data[0] != '{' || e.Data[e.Data.Length - 1] != '}') { return; } WsMessage message = VirtualRoot.JsonSerializer.Deserialize <WsMessage>(e.Data); if (message == null) { return; } switch (message.GetType()) { case WsMessageType.GetSpeed: ws.SendAsync(new WsMessage().SetType(WsMessageType.Speed) .SetData(new Dictionary <string, object> { { "str", "hello" }, { "num", 111 }, { "date", DateTime.Now } }).ToJson(), completed: null); break; default: Write.UserInfo(e.Data); break; } }; ws.OnError += (sender, e) => { Write.UserError(e.Message); }; ws.OnClose += (sender, e) => { Write.UserWarn($"WebSocket Close {e.Code} {e.Reason}"); }; ws.Log.Level = LogLevel.Trace; ws.Connect(); Windows.ConsoleHandler.Register(ws.Close); Console.WriteLine("\nType 'exit' to exit.\n"); while (true) { Console.Write("> "); var action = Console.ReadLine(); if (action == "exit") { break; } if (!ws.IsAlive) { ws.Connect(); } } } }
public static void LocalMessage(LocalMessageChannel channel, string provider, LocalMessageType messageType, string content, OutEnum outEnum, bool toConsole) { switch (outEnum) { case OutEnum.None: break; case OutEnum.Info: Out.ShowInfo(content); break; case OutEnum.Warn: Out.ShowWarn(content, delaySeconds: 4); break; case OutEnum.Error: Out.ShowError(content, delaySeconds: 4); break; case OutEnum.Success: Out.ShowSuccess(content); break; default: break; } if (toConsole) { switch (messageType) { case LocalMessageType.Info: Write.UserInfo(content); break; case LocalMessageType.Warn: Write.UserWarn(content); break; case LocalMessageType.Error: Write.UserError(content); break; default: break; } } Execute(new AddLocalMessageCommand(new LocalMessageData { Id = Guid.NewGuid(), Channel = channel.GetName(), Provider = provider, MessageType = messageType.GetName(), Content = content, Timestamp = DateTime.Now })); }
private static void ContinueCreateProcess(IMineContext mineContext) { Thread.Sleep(1000); if (mineContext != Instance.LockedMineContext) { Write.UserWarn("挖矿停止"); return; } // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { VirtualRoot.RaiseEvent(new StartingMineFailedEvent("内核解压失败,请卸载内核重试。")); } else { Write.UserOk("内核包解压成功"); } // 执行文件书写器 mineContext.ExecuteFileWriters(); // 分离命令名和参数 GetCmdNameAndArguments(mineContext, out string kernelExeFileFullName, out string arguments); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Write.UserError(kernelExeFileFullName + "文件不存在,可能是被杀软删除导致,请退出杀毒软件重试或者QQ群联系小编,解释:大部分挖矿内核会报毒,不是开源矿工的问题也不是杀软的问题,也不是挖矿内核的问题,是挖矿这件事情的问题,可能是挖矿符合了病毒的定义。"); } if (mineContext.KernelProcessType == KernelProcessType.Logfile) { arguments = arguments.Replace(NTKeyword.LogFileParameterName, mineContext.LogFileFullName); } Write.UserOk($"\"{kernelExeFileFullName}\" {arguments}"); Write.UserInfo($"有请内核上场:{mineContext.KernelProcessType}"); if (mineContext != Instance.LockedMineContext) { Write.UserWarn("挖矿停止"); return; } switch (mineContext.KernelProcessType) { case KernelProcessType.Logfile: CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); break; case KernelProcessType.Pip: CreatePipProcess(mineContext, kernelExeFileFullName, arguments); break; default: throw new InvalidProgramException(); } VirtualRoot.RaiseEvent(new MineStartedEvent(mineContext)); }
/// <summary> /// 如果创建失败返回null /// </summary> /// <param name="mqClientTypeName"></param> /// <param name="mqMessagePaths"></param> /// <returns></returns> public static ServerContext Create(string mqClientTypeName, params AbstractMqMessagePath[] mqMessagePaths) { ConnectionMultiplexer redisConn; try { redisConn = ConnectionMultiplexer.Connect(ServerRoot.HostConfig.RedisConfig); } catch (Exception e) { Write.UserError("连接redis失败"); Logger.ErrorDebugLine(e); return(null); } IConnection connection; try { var factory = new ConnectionFactory() { HostName = ServerRoot.HostConfig.MqHostName, UserName = ServerRoot.HostConfig.MqUserName, Password = ServerRoot.HostConfig.MqPassword, AutomaticRecoveryEnabled = true, // 默认值也是true,复数一遍起文档作用 TopologyRecoveryEnabled = true // 默认值也是true,复数一遍起文档作用 }; connection = factory.CreateConnection(mqClientTypeName); } catch (Exception e) { Write.UserError("连接Mq失败"); Logger.ErrorDebugLine(e); return(null); } IModel channel = connection.CreateModel(); channel.ExchangeDeclare(MqKeyword.NTMinerExchange, ExchangeType.Direct, durable: true, autoDelete: false, arguments: null); if (mqMessagePaths != null && mqMessagePaths.Length != 0) { StartConsumer(channel, mqMessagePaths); } return(new ServerContext(redisConn, channel, mqMessagePaths)); }
static void Main() { using (var ws = new WebSocket("ws://localhost:8088/Echo")) { ws.OnOpen += (sender, e) => { Write.UserWarn($"WebSocket Open"); ws.Send("Hi!"); }; ws.OnMessage += (sender, e) => { Write.UserInfo(e.Data); }; ws.OnError += (sender, e) => { Write.UserError(e.Message); }; ws.OnClose += (sender, e) => { Write.UserWarn($"WebSocket Close {e.Code} {e.Reason}"); }; ws.Log.Level = LogLevel.Trace; ws.Connect(); Windows.ConsoleHandler.Register(ws.Close); Console.WriteLine("\nType 'exit' to exit.\n"); while (true) { Console.Write("> "); var msg = Console.ReadLine(); if (msg == "exit") { break; } if (!ws.IsAlive) { ws.Connect(); } // Send a text message. ws.Send(msg); } } }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { Write.UserInfo("清理内核进程"); #if DEBUG VirtualRoot.Stopwatch.Restart(); #endif // 清理除当前外的Temp/Kernel Cleaner.Clear(); #if DEBUG Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(Cleaner)}.{nameof(Cleaner.Clear)}]"); #endif Write.UserOk("内核进程清理完毕"); Thread.Sleep(1000); Write.UserInfo($"解压内核包{mineContext.Kernel.Package}"); // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败,请卸载内核重试。")); } else { Write.UserOk("内核包解压成功"); } // 执行文件书写器 mineContext.ExecuteFileWriters(); Write.UserInfo("总成命令"); // 组装命令 BuildCmdLine(mineContext, out string kernelExeFileFullName, out string arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Write.UserError(kernelExeFileFullName + "文件不存在,可能是小编拼写错误导致,请QQ群联系小编。"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 CreatePipProcess(mineContext, kernelExeFileFullName, arguments); } VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
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 static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { Write.UserInfo("清理内核进程"); HashSet <string> allKernelProcessNames = Instance.KernelSet.GetAllKernelProcessNames(); #if DEBUG VirtualRoot.Stopwatch.Restart(); #endif foreach (var processName in allKernelProcessNames) { Windows.TaskKill.Kill(processName, waitForExit: true); } #if DEBUG Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(allKernelProcessNames)}]"); #endif Write.UserOk("内核进程清理完毕"); Thread.Sleep(1000); Write.UserInfo($"解压内核包{mineContext.Kernel.Package}"); // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { Write.UserFail("内核解压失败"); VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败。")); } else { Write.UserOk("内核包解压成功"); } Write.UserInfo("总成命令"); // 组装命令 BuildCmdLine(mineContext, out var kernelExeFileFullName, out var arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Write.UserError(kernelExeFileFullName + "文件不存在,可能是小编拼写错误导致,请QQ群联系小编。"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 CreatePipProcess(mineContext, kernelExeFileFullName, arguments); } VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
private static void ThisLocalMessage(string provider, LocalMessageType messageType, string content, OutEnum outEnum, bool toConsole) { switch (outEnum) { case OutEnum.None: break; case OutEnum.Info: Out.ShowInfo(content); break; case OutEnum.Warn: Out.ShowWarn(content, delaySeconds: 4); break; case OutEnum.Error: Out.ShowError(content, delaySeconds: 4); break; case OutEnum.Success: Out.ShowSuccess(content); break; case OutEnum.Auto: switch (messageType) { case LocalMessageType.Info: Out.ShowInfo(content); break; case LocalMessageType.Warn: Out.ShowWarn(content, delaySeconds: 4); break; case LocalMessageType.Error: Out.ShowError(content, delaySeconds: 4); break; default: break; } break; default: break; } if (toConsole) { switch (messageType) { case LocalMessageType.Info: Write.UserInfo(content); break; case LocalMessageType.Warn: Write.UserWarn(content); break; case LocalMessageType.Error: Write.UserError(content); break; default: break; } } LocalMessages.Add(LocalMessageChannel.This.GetName(), provider, messageType.GetName(), content); }
public void ShowError(string message, string header = "错误", int autoHideSeconds = 0, bool toConsole = false) { Write.UserError(message); }