/// <summary> /// 这是一次彻底的重连,重新获取服务器地址的重连,以下情况下才会调用该方法: /// 1,进程启动后第一次连接时; /// 2,连不上服务器时; /// 3,收到服务器的WsMessage.ReGetServerAddress类型的消息时; /// </summary> /// <returns></returns> private void NewWebSocket(Action <WebSocket> callback) { RpcRoot.OfficialServer.WsServerNodeService.GetNodeAddressAsync(NTMinerRegistry.GetClientId(_appType), _outerUserId, (response, ex) => { LastTryOn = DateTime.Now; if (!response.IsSuccess()) { IncreaseFailCount(); UpdateNextTrySecondsDelay(); string description; if (response == null || response.ReasonPhrase == null) { description = "网络错误"; } else { description = response.ReadMessage(ex); } UpdateWsStateAsync(description, toOut: false); callback?.Invoke(null); // 退出 return; } string server = response.Data; if (string.IsNullOrEmpty(server)) { IncreaseFailCount(); UpdateNextTrySecondsDelay(); UpdateWsStateAsync("服务器不在线", toOut: false); callback?.Invoke(null); // 退出 return; } var ws = new WebSocket($"ws://{server}/{_appType.GetName()}"); ws.OnOpen += (sender, e) => { ResetFailCount(); UpdateWsStateAsync("连接服务器成功", toOut: false); }; ws.OnMessage += (sender, e) => { if (_ws != ws) { return; } #region if (e.IsPing) { return; } WsMessage message = null; if (e.IsBinary) { message = VirtualRoot.BinarySerializer.Deserialize <WsMessage>(e.RawData); } else // 此时一定IsText,因为取值只有IsBinary、IsPing、IsText这三种 { if (string.IsNullOrEmpty(e.Data) || e.Data[0] != '{' || e.Data[e.Data.Length - 1] != '}') { return; } message = VirtualRoot.JsonSerializer.Deserialize <WsMessage>(e.Data); } if (message == null) { return; } switch (_appType) { case NTMinerAppType.MinerClient: if (message.Type == WsMessage.UpdateAESPassword) { if (message.TryGetData(out AESPassword aesPassword)) { aesPassword.Password = Cryptography.RSAUtil.DecryptString(aesPassword.Password, aesPassword.PublicKey); _aesPassword = aesPassword; } return; } if (_aesPassword == null) { return; } if (message.Sign != message.CalcSign(_aesPassword.Password)) { UpdateWsStateAsync(description: "来自群控的消息签名错误", toOut: true); return; } break;
/// <summary> /// 这是一次彻底的重连,重新获取服务器地址的重连,以下情况下才会调用该方法: /// 1,进程启动后第一次连接时; /// 2,连不上服务器时; /// 3,收到服务器的WsMessage.ReGetServerAddress类型的消息时; /// </summary> /// <returns></returns> private void NewWebSocket() { if (_ws != null) { return; } RpcRoot.OfficialServer.WsServerNodeService.GetNodeAddressAsync(_clientId, _preOuterUserId, (response, ex) => { if (_ws == null) { lock (_wsLocker) { if (_ws == null) { LastTryOn = DateTime.Now; _wsServerIp = string.Empty; #region 网络错误或没有获取到WsServer节点时退出 if (!response.IsSuccess()) { // 没有获取到该矿机的WsServer分片节点,递增失败次数以增大重试延迟周期 IncreaseFailCount(); NextTrySecondsDelayInit(); string description; if (response == null || response.ReasonPhrase == null) { description = "网络错误"; } else { description = response.ReadMessage(ex); } UpdateWsStateAsync(description, toOut: false); // 退出 return; } string server = response.Data; if (string.IsNullOrEmpty(server)) { // 没有获取到该矿机的WsServer分片节点,递增失败次数以增大重试延迟周期 IncreaseFailCount(); NextTrySecondsDelayInit(); UpdateWsStateAsync("服务器不在线", toOut: false); // 退出 return; } _wsServerIp = server; #endregion var ws = new WebSocket($"ws://{server}/{_appType.GetName()}") { Compression = CompressionMethod.Deflate }; ws.Log.File = System.IO.Path.Combine(TempPath.TempLogsDirFullName, string.Format(NTKeyword.WebSocketSharpLogFileNameFormat, _appType.GetName())); ws.Log.Output = WebSocketSharpOutput; ws.OnOpen += new EventHandler(Ws_OnOpen); ws.OnMessage += new EventHandler <MessageEventArgs>(Ws_OnMessage); ws.OnError += new EventHandler <ErrorEventArgs>(Ws_OnError); ws.OnClose += new EventHandler <CloseEventArgs>(Ws_OnClose); ConnectAsync(ws); _ws = ws; } } } }); }