public static void HandleMinerClientMessage(IWsSessionAdapter session, WsMessage message) { if (message == null) { return; } if (!MinerClientSessionSet.TryGetByWsSessionId(session.SessionId, out IMinerClientSession minerSession)) { session.CloseAsync(WsCloseCode.Normal, "意外,会话不存在,请重新连接"); return; } else if (WsMessageFromMinerClientHandler.TryGetHandler(message.Type, out Action <IMinerClientSession, Guid, WsMessage> handler)) { try { handler.Invoke(minerSession, minerSession.ClientId, message); } catch (Exception ex) { Logger.ErrorDebugLine(ex); } } else { NTMinerConsole.UserWarn($"{nameof(HandleMinerClientMessage)} Received InvalidType {message.Type}"); } }
public static void ActiveMinerClientSession(string sessionId) { if (MinerClientSessionSet.ActiveByWsSessionId(sessionId, out IMinerClientSession minerSession)) { MqBufferRoot.Breath(minerSession.ClientId); } }
public static void ActiveMinerClientSession(string sessionId) { if (MinerClientSessionSet.ActiveByWsSessionId(sessionId, out IMinerClientSession minerSession)) { MinerClientMqSender.SendMinerClientWsBreathed(minerSession.LoginName, minerSession.ClientId); } }
static void Main() { NTMinerConsole.SetIsMainUiOk(true); NTMinerConsole.DisbleQuickEditMode(); DevMode.SetDevMode(); Windows.ConsoleHandler.Register(Exit); string thisServerAddress = ServerRoot.HostConfig.ThisServerAddress; Console.Title = $"{ServerAppType.WsServer.GetName()}_{thisServerAddress}"; // 通过WsServer的网络缓解对WebApiServer的外网流量的压力。WsServer调用WebApiServer的时候走内网调用节省外网带宽 RpcRoot.SetOfficialServerAddress(ServerRoot.HostConfig.RpcServerLocalAddress); // 用本节点的地址作为队列名,消费消息时根据路由键区分消息类型 string queue = $"{ServerAppType.WsServer.GetName()}.{thisServerAddress}"; string durableQueue = queue + MqKeyword.DurableQueueEndsWith; AbstractMqMessagePath[] mqMessagePaths = new AbstractMqMessagePath[] { new ReadOnlyUserMqMessagePath(durableQueue), new MinerSignMqMessagePath(durableQueue), new WsServerNodeMqMessagePath(queue), new OperationMqMessagePath(queue), new MinerClientMqMessagePath(queue, thisServerAddress) }; if (!MqRedis.Create(ServerAppType.WsServer, mqMessagePaths, out IMqRedis mqRedis)) { NTMinerConsole.UserError("启动失败,无法继续,因为服务器上下文创建失败"); return; } MinerClientMqSender = new MinerClientMqSender(mqRedis); SpeedDataRedis = new SpeedDataRedis(mqRedis); WsServerNodeRedis = new WsServerNodeRedis(mqRedis); OperationMqSender = new OperationMqSender(mqRedis); UserMqSender = new UserMqSender(mqRedis); _wsServerNodeMqSender = new WsServerNodeMqSender(mqRedis); WsServerNodeAddressSet = new WsServerNodeAddressSet(WsServerNodeRedis, _wsServerNodeMqSender); var minerRedis = new ReadOnlyMinerRedis(mqRedis); var userRedis = new ReadOnlyUserRedis(mqRedis); VirtualRoot.StartTimer(); RpcRoot.SetRpcUser(new RpcUser(ServerRoot.HostConfig.RpcLoginName, HashUtil.Sha1(ServerRoot.HostConfig.RpcPassword))); RpcRoot.SetIsOuterNet(false); // 构造函数中异步访问redis初始化用户列表,因为是异步的所以提前构造 UserSet = new ReadOnlyUserSet(userRedis); MinerSignSet = new MinerSignSet(minerRedis); _wsServer = new SharpWsServerAdapter(ServerRoot.HostConfig); MinerClientSessionSet = new MinerClientSessionSet(_wsServer.MinerClientWsSessions); MinerStudioSessionSet = new MinerStudioSessionSet(_wsServer.MinerStudioWsSessions); _started = _wsServer.Start(); if (!_started) { NTMinerConsole.UserError("启动失败,无法继续,因为_wsServer启动失败"); return; } VirtualRoot.RaiseEvent(new WebSocketServerStatedEvent()); Console.ReadKey(true); Exit(); }
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); } }
public static void RemoveMinerClientSession(string sessionId) { IMinerClientSession minerSession = MinerClientSessionSet.RemoveByWsSessionId(sessionId); if (minerSession != null) { MinerClientMqSender.SendMinerClientWsClosed(minerSession.ClientId); } }
public static void ActiveMinerClientSession(string sessionId) { if (MinerClientSessionSet.ActiveByWsSessionId(sessionId, out IMinerClientSession minerSession)) { lock (_lockerForToBreathClientIds) { _toBreathClientIds.Add(minerSession.ClientId); } } }
static void Main() { VirtualRoot.SetOut(new ConsoleOut()); NTMinerConsole.MainUiOk(); NTMinerConsole.DisbleQuickEditMode(); DevMode.SetDevMode(); Windows.ConsoleHandler.Register(Exit); string thisServerAddress = ServerRoot.HostConfig.ThisServerAddress; Console.Title = $"{nameof(ServerAppType.WsServer)}_{thisServerAddress}"; // 用本节点的地址作为队列名,消费消息时根据路由键区分消息类型 string queue = $"{nameof(ServerAppType.WsServer)}.{thisServerAddress}"; string durableQueue = queue + MqKeyword.DurableQueueEndsWith; AbstractMqMessagePath[] mqMessagePaths = new AbstractMqMessagePath[] { new ReadOnlyUserMqMessagePath(durableQueue), new MinerSignMqMessagePath(queue), new WsServerNodeMqMessagePath(queue), new OperationMqMessagePath(queue), new MinerClientMqMessagePath(queue, thisServerAddress), new ClientTestIdMqMessagePath(queue) }; if (!MqRedis.Create(ServerAppType.WsServer, mqMessagePaths, out IMqRedis mqRedis)) { NTMinerConsole.UserError("启动失败,无法继续,因为服务器上下文创建失败"); return; } MinerClientMqSender = new MinerClientMqSender(mqRedis); SpeedDataRedis = new SpeedDataRedis(mqRedis); WsServerNodeRedis = new WsServerNodeRedis(mqRedis); OperationMqSender = new OperationMqSender(mqRedis); UserMqSender = new UserMqSender(mqRedis); _wsServerNodeMqSender = new WsServerNodeMqSender(mqRedis); WsServerNodeAddressSet = new WsServerNodeAddressSet(WsServerNodeRedis, _wsServerNodeMqSender); var minerRedis = new MinerDataRedis(mqRedis); var userRedis = new ReadOnlyUserDataRedis(mqRedis); VirtualRoot.StartTimer(); // 构造函数中异步访问redis初始化用户列表,因为是异步的所以提前构造 UserSet = new ReadOnlyUserSet(userRedis); MinerSignSet = new MinerSignSet(minerRedis); _wsServer = new SharpWsServerAdapter(ServerRoot.HostConfig); MinerClientSessionSet = new MinerClientSessionSet(_wsServer.MinerClientWsSessions); MinerStudioSessionSet = new MinerStudioSessionSet(_wsServer.MinerStudioWsSessions); _started = _wsServer.Start(); if (!_started) { NTMinerConsole.UserError("启动失败,无法继续,因为_wsServer启动失败"); return; } VirtualRoot.RaiseEvent(new WebSocketServerStatedEvent()); Console.ReadKey(true); Exit(); }