Selaa lähdekoodia

fix : 用户注册加线程锁, token活跃更新

bilingfeng 1 vuosi sitten
vanhempi
commit
a803cd3c7b

+ 1 - 1
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/SDKApplication.java

@@ -23,7 +23,7 @@ public class SDKApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(SDKApplication.class, args);
-        System.out.println("赞象SDK服务启动成功 <解决微信和支付宝支付逻辑中的高并发引起的全局变量bug> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象SDK服务启动成功 <用户注册加线程锁, token活跃更新> ( ´・・)ノ(._.`) \n" +
                 " ___________ _   __\n" +
                 "/  ___|  _  \\ | / /\n" +
                 "\\ `--.| | | | |/ / \n" +

+ 5 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/constant/RedisKeyConstant.java

@@ -47,4 +47,9 @@ public class RedisKeyConstant {
      */
     public static final String ORDER_EXPIRE_LOCK = RedisKeyConstant.REDIS_PREFIX + "order_expire_lock_";
 
+    /**
+     * 用户注册
+     */
+    public static final String USER_CREATE = RedisKeyConstant.REDIS_PREFIX + "user_create";
+
 }

+ 7 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/IUserTokenService.java

@@ -24,6 +24,13 @@ public interface IUserTokenService extends IService<UserToken> {
      */
     ResultVO<Long> cpTokenCheck(String appId, Long userId, String token, String sign);
 
+    /**
+     * 用户活跃token更新
+     *
+     * @param userData 用户数据
+     */
+    void userTokenUpdateCheck(UserData userData);
+
     /**
      * 用户令牌到期时间检查
      *

+ 10 - 6
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/GameUserRoleServiceImpl.java

@@ -14,10 +14,7 @@ import com.zanxiang.game.module.sdk.enums.LoginTypeEnum;
 import com.zanxiang.game.module.sdk.pojo.param.GameRoleActiveCallParam;
 import com.zanxiang.game.module.sdk.pojo.param.GameUserRoleUpdateParam;
 import com.zanxiang.game.module.sdk.pojo.param.UserData;
-import com.zanxiang.game.module.sdk.service.IGameUserRoleService;
-import com.zanxiang.game.module.sdk.service.IGameUserService;
-import com.zanxiang.game.module.sdk.service.IUserLoginLogService;
-import com.zanxiang.game.module.sdk.service.IUserService;
+import com.zanxiang.game.module.sdk.service.*;
 import com.zanxiang.module.redis.service.IDistributedLockComponent;
 import com.zanxiang.module.util.DateUtil;
 import com.zanxiang.module.util.JsonUtil;
@@ -58,6 +55,9 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
     @Autowired
     private IDistributedLockComponent distributedLockComponent;
 
+    @Autowired
+    private IUserTokenService userTokenService;
+
     @Value("${spring.kafka.game-sdk.gameRoleActiveTopic}")
     private String gameRoleActiveTopic;
 
@@ -241,8 +241,12 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
 
     @Override
     public boolean gameRoleActiveCall(UserData userData, GameRoleActiveCallParam param) {
-        log.error("接收到前端用户角色活跃上报, userId : {}, gameId : {}, serverId : {}, roleId : {}, roleLevel : {}",
-                userData.getUserId(), userData.getGameId(), param.getServerId(), param.getRoleId(), param.getRoleLevel());
+        //token临期失效判断
+        try {
+            userTokenService.userTokenUpdateCheck(userData);
+        } catch (Exception ignored) {
+        }
+        //活跃提交
         Map<String, Object> activeParamMap = new HashMap<>(6);
         activeParamMap.put("userId", userData.getUserId());
         activeParamMap.put("gameId", userData.getGameId());

+ 15 - 4
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/LoginServiceImpl.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.zanxiang.game.module.base.pojo.enums.BanStatusEnum;
 import com.zanxiang.game.module.base.pojo.enums.HttpStatusEnum;
 import com.zanxiang.game.module.mybatis.entity.*;
+import com.zanxiang.game.module.sdk.constant.RedisKeyConstant;
 import com.zanxiang.game.module.sdk.enums.LoginTypeEnum;
 import com.zanxiang.game.module.sdk.enums.SmsTypeEnum;
 import com.zanxiang.game.module.sdk.pojo.dto.GameAppletDTO;
@@ -17,7 +18,9 @@ import com.zanxiang.game.module.sdk.service.*;
 import com.zanxiang.game.module.sdk.service.api.WxApiService;
 import com.zanxiang.game.module.sdk.util.RegexUtil;
 import com.zanxiang.game.module.sdk.util.RegisterUtil;
+import com.zanxiang.module.redis.service.IDistributedLockComponent;
 import com.zanxiang.module.util.JsonUtil;
+import com.zanxiang.module.util.exception.BaseException;
 import com.zanxiang.module.util.pojo.ResultVO;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.logging.log4j.util.Strings;
@@ -31,6 +34,7 @@ import reactor.util.function.Tuples;
 import java.time.LocalDateTime;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author : lingfeng
@@ -95,6 +99,9 @@ public class LoginServiceImpl implements IRegisterLoginService {
     @Autowired
     private IGameUserRoleService gameUserRoleService;
 
+    @Autowired
+    private IDistributedLockComponent distributedLockComponent;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public ResultVO<UserLoginVO> loginWxCode(LoginVxCodeParam param, UserData userData) {
@@ -109,10 +116,6 @@ public class LoginServiceImpl implements IRegisterLoginService {
                 gameAppletDTO.getAppSecret(), gameAppletDTO.getType());
         String openId = resultMap.get("openid");
         String sessionKey = resultMap.get("session_key");
-
-        log.error("登录用户, param : {}, userData : {}, resultMap : {}", JsonUtil.toString(param),
-                JsonUtil.toString(userData), JsonUtil.toString(resultMap));
-
         //根据openId查询用户
         User user = userService.getOne(new LambdaQueryWrapper<User>()
                 .eq(User::getGameId, userData.getGameId()).eq(User::getOpenId, openId));
@@ -269,6 +272,12 @@ public class LoginServiceImpl implements IRegisterLoginService {
     }
 
     private User userCreateSave(UserData userData, String userName, String password, String mobile, String openId, String sessionKey) {
+        //锁Key
+        String lockKey = RedisKeyConstant.USER_CREATE + "_" + userData.getGameId() + "_" + userName;
+        //上锁
+        if (!distributedLockComponent.doLock(lockKey, 3L, 10L, TimeUnit.SECONDS)) {
+            throw new BaseException("用户信息正在注册中, 请稍后重试");
+        }
         //渠道id, 链接参数, 分享人id
         Tuple3<Long, Map<String, String>, String> tuple3 = agentService.getUserAgentId(userData);
         //分享人id
@@ -297,6 +306,8 @@ public class LoginServiceImpl implements IRegisterLoginService {
                 .createTime(LocalDateTime.now())
                 .updateTime(LocalDateTime.now())
                 .build());
+        //释放锁
+        distributedLockComponent.unlock(lockKey);
         return user;
     }
 

+ 21 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/UserTokenServiceImpl.java

@@ -1,6 +1,7 @@
 package com.zanxiang.game.module.sdk.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.game.module.base.pojo.enums.BanStatusEnum;
 import com.zanxiang.game.module.base.util.DateUtils;
@@ -17,6 +18,7 @@ import com.zanxiang.game.module.sdk.pojo.param.UserData;
 import com.zanxiang.game.module.sdk.service.*;
 import com.zanxiang.game.module.sdk.util.RedisUtil;
 import com.zanxiang.game.module.sdk.util.SignUtil;
+import com.zanxiang.module.util.DateUtil;
 import com.zanxiang.module.util.JsonUtil;
 import com.zanxiang.module.util.bean.BeanUtil;
 import com.zanxiang.module.util.encryption.Md5Util;
@@ -105,6 +107,25 @@ public class UserTokenServiceImpl extends ServiceImpl<UserTokenMapper, UserToken
         return re;
     }
 
+    @Override
+    public void userTokenUpdateCheck(UserData userData) {
+        //过期时间
+        LocalDateTime expireTime = DateUtil.secondToLocalDateTime(userData.getExpireTime());
+        //判断是否1天内过期
+        if (expireTime == null || LocalDateTime.now().plusDays(1).isBefore(expireTime)) {
+            return;
+        }
+        //更新token的时效时长
+        super.update(new LambdaUpdateWrapper<UserToken>()
+                .set(UserToken::getExpireTime, DateUtils.localDateTimeToSecond(LocalDateTime.now()) + ExpireTimeEnum.ONE_WEEK.getTime())
+                .set(UserToken::getUpdateTime, LocalDateTime.now())
+                .eq(UserToken::getUserId, userData.getUserId())
+                .eq(UserToken::getToken, userData.getToken()));
+        //删除token信息缓存
+        redisUtil.deleteCache(this.getTokenInfoKey(userData.getToken(), userData.getDeviceType()));
+        redisUtil.deleteCache(this.getUserTokenKey(userData.getUserId(), userData.getDeviceType()));
+    }
+
     @Override
     public Boolean userTokenExpireTimeCheck(UserData userData) {
         log.error("缓存token验证请求 userData : {}", JsonUtil.toString(userData));