欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 【redis的使用、账号流程、游戏服Handler的反射调用】1.自增id 2.全局用户名这样子名字唯一 3.

【redis的使用、账号流程、游戏服Handler的反射调用】1.自增id 2.全局用户名这样子名字唯一 3.

2024/12/22 18:03:49 来源:https://blog.csdn.net/themagickeyjianan/article/details/144578524  浏览:    关键词:【redis的使用、账号流程、游戏服Handler的反射调用】1.自增id 2.全局用户名这样子名字唯一 3.

一、web服

1)账号注册 // 用于唯一命名服务

com.xinyue.game.center.business.account.logic.AccountRegisterService#accountRegister

 public void accountRegister(AccountEntity account) {accountManager.checkUsername(account.getUsername());accountManager.checkPassword(account.getPassword());checkUsernameHaveRegister(account.getUsername());// 注册的用户名,立马用redis保存下boolean saveResult = accountRedisManager.saveUsername(account.getUsername());if (saveResult) {AccountEntity saveAccount = accountDao.save(account);account.setId(saveAccount.getId());logger.info("用户注册成功,username:{}", account.getUsername());} else {throw ServerErrorCode.ACCOUNT_1005.exception();}}

唯一性实现

 public boolean saveUsername(String username) {String value = String.valueOf(System.currentTimeMillis());return redisTemplate.opsForValue().setIfAbsent(username, value, Duration.ofHours(USERNAME_EXPIRE_HOURS));}

经过注册后,进行登录

2)角色注册 / redis自增

com.xinyue.game.center.business.role.RoleService#createRole

    public CreateRoleResponse createRole(CreateRoleRequest createRoleParam) throws Exception {AccountEntity accountEntity = accountService.getAndCheckAccount(createRoleParam.getUserId());createRoleManager.checkNicknameSensitive(createRoleParam.getNickname());createRoleManager.checkRoleExist(accountEntity, createRoleParam.getZoneId());// 创建角色,这一步是会使用redis的自增PlayerEntity roleEntity = createRoleManager.createRole(createRoleParam);ZoneRoleEntity zoneRoleEntity = createRoleManager.getZoneRole(roleEntity);accountEntity.getSectionPlayerMap().put(createRoleParam.getZoneId(), zoneRoleEntity);accountService.updateAccount(accountEntity);CreateRoleResponse createRoleResponse = new CreateRoleResponse();createRoleResponse.setPlayerId(zoneRoleEntity.getPlayerId());createRoleResponse.setNickname(roleEntity.getNickname());createRoleResponse.setCreateTime(roleEntity.getCreateTime());createRoleResponse.setLastLoginTime(roleEntity.getCreateTime());String token = this.createToken(roleEntity);createRoleResponse.setToken(token);return createRoleResponse;}

自增实现

  public String generateRoleId(String zoneId) {String key = getKey(zoneId);long roleId = redisTemplate.opsForValue().increment(key);return zoneId + "_" + roleId;}

二、游戏服

1.请求进入游戏 // 携带userId 和 playerId和token

com.xinyue.game.server.logic.player.PlayerHandler#enterGame

   @GameMapping(EnterGameRequest.class)public void enterGame(GameChannelContext ctx, EnterGameRequest request) {String userId = request.getUserId();userService.checkUserId(userId);userService.checkToken(userId, request.getToken());logger.debug("用户认证成功,userId: {},token:{}", userId, request.getToken());this.bindChannel(ctx.getNettyCtx(), request.getPlayerId());gameAsyncTaskService.execute(request.getPlayerId(), "获取玩家信息", () -> {PlayerEntity playerEntity = playerCacheService.getPlayerOrLoading(request.getPlayerId());if (playerEntity == null) {ctx.writeAndFlush(EnumGameError.ROLE_NOT_EXIST);} else {EnterGameResponse response = new EnterGameResponse();response.setRole(playerEntity);ctx.writeAndFlush(response);}});}

可见,核心是GameChannelContext!!!

这个上下文是如何构建的呢?

com.xinyue.server.framework.handler.GameRequestDispatcherHandler#channelRead

    @Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof GameMessagePackage) {try {GameMessagePackage request = (GameMessagePackage) msg;IGameMessage gameMessage = request.getBody();GameMessageHeader header = request.getHeader();// 重点就是这一步了GameChannelContext gtx = new GameChannelContext(ctx, header);IGameMessage requestMessage = gameMessage;int messageId = header.getLogicMessageId();int messageType = GameMessageType.REQUEST.getType();MessageClassKey classKey = new MessageClassKey(messageId, messageType);GameHandlerMappingManager gameHandlerMappingManager = GameHandlerMappingManager.getInstance();// 进行反射调用。 这一步的消息其实可以包装到上下文中。gameHandlerMappingManager.callMethod(gtx, classKey, requestMessage);} catch (Throwable e) {logger.error("处理客户端请求异常", e);}} else {logger.warn("收到非游戏对象请求数据:{}", msg.getClass().getName());ctx.fireChannelRead(msg);}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com