Example #1
0
        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;
            }
        }
Example #2
0
        /// <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;
Example #3
0
        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
        }