public void SendAsync(WsMessage message) { if (!IsOpen) { return; } switch (_appType) { case NTMinerAppType.MinerClient: _ws.SendAsync(message.ToBytes(), null); break; case NTMinerAppType.MinerStudio: _ws.SendAsync(message.SignToBytes(RpcRoot.RpcUser.Password), null); break; default: break; } }
/// <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;
private void Ws_OnMessage(object sender, MessageEventArgs e) { WebSocket ws = (WebSocket)sender; 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; case NTMinerAppType.MinerStudio: if (message.Type == WsMessage.ReLogin) { UpdateWsStateAsync(description: "用户密码已变更,请重新登录", toOut: true); return; } if (message.Sign != message.CalcSign(RpcRoot.RpcUser.Password)) { UpdateWsStateAsync(description: "来自群控的消息签名错误", toOut: true); return; } break; default: break; } if (message.Type == WsMessage.ReGetServerAddress) { ws.CloseAsync(CloseStatusCode.Normal, WsMessage.ReGetServerAddress); return; } if (TryGetHandler(message.Type, out Action <Action <WsMessage>, WsMessage> handler)) { handler.Invoke(SendAsync, message); } else { NTMinerConsole.DevWarn(() => $"OnMessage Received InvalidType {e.Data}"); } #endregion }