예제 #1
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;
예제 #2
0
        /// <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;
                        }
                    }
                }
            });
        }