private void ConnectAsync(WebSocket ws) { if (ws == null) { return; } if (ws.ReadyState == WebSocketState.Open) { return; } // WebSocketSharp内部限定了连接重试次数,这不符合我们的业务逻辑,这里通过反射赋值使WebSocketSharp的重试次数限制失效。 _retryCountForConnectFieldInfo.SetValue(ws, 1); WsUserName userName = new WsUserName { ClientType = _appType, ClientVersion = EntryAssemblyInfo.CurrentVersionStr, ClientId = _clientId, UserId = _preOuterUserId, IsBinarySupported = true }; string userNameJson = VirtualRoot.JsonSerializer.Serialize(userName); string password = string.Empty; if (_appType == NTMinerAppType.MinerStudio) { password = RpcRoot.RpcUser.Password; } string base64String = Convert.ToBase64String(Encoding.UTF8.GetBytes(userNameJson)); password = HashUtil.Sha1(base64String + password); // SetCredentials要求username不能带:号,所以必须编码 ws.SetCredentials(base64String, password, preAuth: true); LastTryOn = DateTime.Now; ws.ConnectAsync(); }
public static void AddMinerClientSession(WsUserName wsUserName, UserData userData, IPEndPoint remoteEndPoint, IWsSessionAdapter session) { IMinerClientSession minerSession = MinerClientSession.Create(userData, wsUserName, remoteEndPoint, session.SessionId, WsServer.MinerClientWsSessions); MinerClientSessionSet.Add(minerSession); // 通知WebApiServer节点该矿机Ws连线了 MinerClientMqSender.SendMinerClientWsOpened(minerSession.LoginName, minerSession.ClientId); bool isMinerSignChanged; if (!MinerSignSet.TryGetByClientId(wsUserName.ClientId, out MinerSign minerSign)) { // 此时该矿机是第一次在服务端出现 minerSign = new MinerSign { Id = LiteDB.ObjectId.NewObjectId().ToString(), ClientId = wsUserName.ClientId, LoginName = userData.LoginName, OuterUserId = wsUserName.UserId, AESPassword = string.Empty, AESPasswordOn = Timestamp.UnixBaseTime }; isMinerSignChanged = true; } else { isMinerSignChanged = minerSign.OuterUserId != wsUserName.UserId || minerSign.LoginName != userData.LoginName; if (isMinerSignChanged) { minerSign.OuterUserId = wsUserName.UserId; minerSign.LoginName = userData.LoginName; } } // 通常执行不到,因为用户注册的时候已经生成了RSA公私钥对了 if (string.IsNullOrEmpty(userData.PublicKey) || string.IsNullOrEmpty(userData.PrivateKey)) { var key = Cryptography.RSAUtil.GetRASKey(); userData.PublicKey = key.PublicKey; userData.PrivateKey = key.PrivateKey; UserMqSender.SendUpdateUserRSAKey(userData.LoginName, key); } DateTime now = DateTime.Now; if (string.IsNullOrEmpty(minerSign.AESPassword) || minerSign.AESPasswordOn.AddDays(1) < now) { isMinerSignChanged = true; minerSign.AESPassword = Cryptography.AESUtil.GetRandomPassword(); minerSign.AESPasswordOn = now; } session.SendAsync(new WsMessage(Guid.NewGuid(), WsMessage.UpdateAESPassword) { Data = new AESPassword { PublicKey = userData.PublicKey, Password = Cryptography.RSAUtil.EncryptString(minerSign.AESPassword, userData.PrivateKey) } }.SignToJson(minerSign.AESPassword)); if (isMinerSignChanged) { MinerClientMqSender.SendChangeMinerSign(minerSign); } }
/// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="wsSessionID"></param> public AbstractSession(IUser user, WsUserName userName, string wsSessionID) { this.ClientId = userName.ClientId; this.ClientVersion = userName.ClientVersion; this.LoginName = user.LoginName; this.ActiveOn = DateTime.Now; this.WsSessionId = wsSessionID; }
/// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="wsSessionID"></param> public AbstractSession(IUser user, WsUserName wsUserName, string wsSessionID, IWsSessionsAdapter sessions) { _sessions = sessions; this.WsUserName = wsUserName; this.ClientId = wsUserName.ClientId; this.ClientVersion = Version.Parse(wsUserName.ClientVersion);// 因为前面的流程已经过验证所以可以直接Parse this.LoginName = user.LoginName; this.ActiveOn = DateTime.Now; this.WsSessionId = wsSessionID; }
/// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="wsSessionID"></param> public AbstractSession(IUser user, WsUserName wsUserName, string wsSessionID, WebSocketSessionManager wsSessionManager) { _wsSessionManager = wsSessionManager; this.WsUserName = wsUserName; this.ClientId = wsUserName.ClientId; this.ClientVersion = Version.Parse(wsUserName.ClientVersion);// 因为前面的流程已经过验证所以可以直接Parse this.LoginName = user.LoginName; this.ActiveOn = DateTime.Now; this.WsSessionId = wsSessionID; }
public static void AddMinerStudioSession(WsUserName wsUserName, UserData userData, IPEndPoint remoteEndPoint, IWsSessionAdapter session) { IMinerStudioSession minerSession = MinerStudioSession.Create(userData, wsUserName, remoteEndPoint, session.SessionId, WsServer.MinerStudioWsSessions); MinerStudioSessionSet.Add(minerSession); session.SendAsync(new WsMessage(Guid.NewGuid(), WsMessage.ServerTime) { Data = Timestamp.GetTimestamp() }.SignToBytes(userData.Password)); }
public static string GetUserPassword(WsUserName wsUserName, UserData userData) { string password; switch (wsUserName.ClientType) { case NTMinerAppType.MinerClient: password = string.Empty; break; case NTMinerAppType.MinerStudio: password = userData.Password; break; default: password = string.Empty; break; } return(password); }
public static bool TryGetUser(string base64String, out WsUserName wsUserName, out UserData userData, out string errMsg) { wsUserName = null; userData = null; errMsg = string.Empty; if (string.IsNullOrEmpty(base64String)) { errMsg = $"{nameof(base64String)}为空"; return(false); } string json = Encoding.UTF8.GetString(Convert.FromBase64String(base64String)); wsUserName = VirtualRoot.JsonSerializer.Deserialize <WsUserName>(json); if (wsUserName == null) { errMsg = $"{nameof(base64String)}编码的json字符串格式错误"; return(false); } if (!wsUserName.IsValid()) { errMsg = "wsUserName提交的数据无效"; return(false); } userData = UserSet.GetUser(UserId.Create(wsUserName.UserId)); if (userData == null) { errMsg = $"用户{wsUserName.UserId}不存在"; return(false); } if (!userData.IsEnabled) { errMsg = $"用户{wsUserName.UserId}已被禁用"; return(false); } return(true); }
public static MinerClientSession Create(IUser user, WsUserName userName, string wsSessionID) { return(new MinerClientSession(user, userName, wsSessionID)); }
private MinerClientSession(IUser user, WsUserName userName, string wsSessionID) : base(user, userName, wsSessionID) { }
public static bool TryGetUser(this WebSocketBehavior behavior, out WsUserName wsUserName, out UserData userData) { string base64String = behavior.Context.User.Identity.Name; return(WsRoot.TryGetUser(base64String, out wsUserName, out userData)); }
private MinerClientSession(IUser user, WsUserName wsUserName, string wsSessionID, WebSocketSessionManager wsSessionManager) : base(user, wsUserName, wsSessionID, wsSessionManager) { }
/// <summary> /// 不会返回null /// </summary> /// <param name="user"></param> /// <param name="wsUserName"></param> /// <param name="wsSessionID"></param> /// <param name="wsSessionManager"></param> /// <returns></returns> public static MinerClientSession Create(IUser user, WsUserName wsUserName, string wsSessionID, WebSocketSessionManager wsSessionManager) { return(new MinerClientSession(user, wsUserName, wsSessionID, wsSessionManager)); }
private MinerClientSession(IUser user, WsUserName wsUserName, string wsSessionID, IWsSessionsAdapter sessions) : base(user, wsUserName, wsSessionID, sessions) { }
private MinerStudioSession(IUser user, WsUserName userName, string wsSessionID) : base(user, userName, wsSessionID) { }
private MinerClientSession( IUser user, WsUserName wsUserName, IPEndPoint remoteEndPoint, string wsSessionID, IWsSessionsAdapter wsSessions) : base(user, wsUserName, remoteEndPoint, wsSessionID, wsSessions) { }
/// <summary> /// 不会返回null /// </summary> /// <param name="user"></param> /// <param name="wsUserName"></param> /// <param name="remoteEndPoint"></param> /// <param name="wsSessionID"></param> /// <param name="wsSessions"></param> /// <returns></returns> public static MinerClientSession Create( IUser user, WsUserName wsUserName, IPEndPoint remoteEndPoint, string wsSessionID, IWsSessionsAdapter wsSessions) { return(new MinerClientSession(user, wsUserName, remoteEndPoint, wsSessionID, wsSessions)); }
/// <summary> /// 不会返回null /// </summary> /// <param name="user"></param> /// <param name="wsUserName"></param> /// <param name="wsSessionID"></param> /// <param name="sessions"></param> /// <returns></returns> public static MinerClientSession Create(IUser user, WsUserName wsUserName, string wsSessionID, IWsSessionsAdapter sessions) { return(new MinerClientSession(user, wsUserName, wsSessionID, sessions)); }
private MinerStudioSession(IUser user, WsUserName userName, string wsSessionID, WebSocketSessionManager wsSessionManager) : base(user, userName, wsSessionID, wsSessionManager) { }