yangyale преди 1 година
родител
ревизия
708d76d4ff

+ 25 - 0
src/main/java/com/hy/modules/bz/config/WebSocketConfig.java

@@ -0,0 +1,25 @@
+package com.hy.modules.bz.config;
+
+import com.hy.modules.bz.websocket.BarrageWebSocketServer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+
+import static com.hy.modules.bz.websocket.BarrageWebSocketServer.PATH;
+
+@Configuration
+@EnableWebSocket
+public class WebSocketConfig implements WebSocketConfigurer {
+
+    @Override
+    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+        registry.addHandler(barrageWebSocketServer(),PATH);
+    }
+
+    @Bean
+    public BarrageWebSocketServer barrageWebSocketServer() {
+        return new BarrageWebSocketServer();
+    }
+}

+ 29 - 0
src/main/java/com/hy/modules/bz/utils/TokenStatusManager.java

@@ -0,0 +1,29 @@
+package com.hy.modules.bz.utils;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class TokenStatusManager {
+    private static final TokenStatusManager instance = new TokenStatusManager();
+
+    private TokenStatusManager() {
+    }
+
+    private final Map<String,Integer> tokenSignalMap = new ConcurrentHashMap<>();
+
+    public static TokenStatusManager getInstance() {
+        return instance;
+    }
+
+    public void sendSignal(String token){
+        tokenSignalMap.put(token,1);
+    }
+
+    public void removeSignal(String token){
+        tokenSignalMap.remove(token);
+    }
+
+    public boolean isInSignal(String token){
+        return tokenSignalMap.containsKey(token);
+    }
+}

+ 24 - 0
src/main/java/com/hy/modules/bz/webapi/ErrorCode.java

@@ -0,0 +1,24 @@
+package com.hy.modules.bz.webapi;
+
+public enum ErrorCode {
+    NO_PLAYER_FOUND(300,"账号不存在或密码错误!"),
+
+    TOKEN_EXPIRED(301,"token已过期,请重新登录!"),
+
+    ;
+    private int code;
+    private String errorMsg;
+
+    ErrorCode(int code, String errorMsg) {
+        this.code = code;
+        this.errorMsg = errorMsg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getErrorMsg() {
+        return errorMsg;
+    }
+}

+ 8 - 1
src/main/java/com/hy/modules/bz/webapi/controller/BzWebApiController.java

@@ -2,6 +2,7 @@ package com.hy.modules.bz.webapi.controller;
 
 import com.hy.common.web.base.BaseController;
 import com.hy.common.web.domain.response.Result;
+import com.hy.modules.bz.webapi.ErrorCode;
 import com.hy.modules.bz.webapi.dto.*;
 import com.hy.modules.bz.webapi.service.WebApiService;
 import io.swagger.annotations.Api;
@@ -27,7 +28,13 @@ public class BzWebApiController extends BaseController {
         try{
             return success(apiService.login(loginInfo));
         }catch (Exception ex){
-            return failure(ex.getMessage());
+            if(ErrorCode.NO_PLAYER_FOUND.getErrorMsg().equals(ex.getMessage())){
+                return failure(ErrorCode.NO_PLAYER_FOUND.getCode(),ex.getMessage(),null);
+            }else if(ErrorCode.TOKEN_EXPIRED.getErrorMsg().equals(ex.getMessage())){
+                return failure(ErrorCode.TOKEN_EXPIRED.getCode(),ex.getMessage(),null);
+            }else{
+                return failure(ex.getMessage());
+            }
         }
     }
 

+ 5 - 0
src/main/java/com/hy/modules/bz/webapi/dto/LoginInfoDto.java

@@ -28,4 +28,9 @@ public class LoginInfoDto implements Serializable {
      * 时间戳 必传
      */
     private long timestamp;
+
+    /**
+     * 掉线重连需要
+     */
+    private String token;
 }

+ 20 - 9
src/main/java/com/hy/modules/bz/webapi/service/impl/WebApiServiceImpl.java

@@ -6,8 +6,11 @@ import com.hy.modules.bz.domain.BzAnchorStudio;
 import com.hy.modules.bz.domain.BzPlayer;
 import com.hy.modules.bz.service.IBzAnchorStudioService;
 import com.hy.modules.bz.service.IBzPlayerService;
+import com.hy.modules.bz.utils.TokenStatusManager;
+import com.hy.modules.bz.webapi.ErrorCode;
 import com.hy.modules.bz.webapi.dto.*;
 import com.hy.modules.bz.webapi.service.WebApiService;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.data.redis.core.StringRedisTemplate;
@@ -44,16 +47,24 @@ public class WebApiServiceImpl implements WebApiService {
                     .eq("card_password",loginInfo.getCardPwd())
                     .eq("status","normal");
             BzPlayer player = playerService.getOne(queryWrapper,false);
-            Assert.notNull(player,"No player found");
-
-            String toEncode = UUID.randomUUID().toString().concat(String.valueOf(loginInfo.getTimestamp()));
-            String token = EncodeUtils.customBase64Encode(toEncode);
-            stringRedisTemplate.opsForValue().set(TOKEN_PRIFIX.concat(loginInfo.getCardNo()),token);
+            Assert.notNull(player,ErrorCode.NO_PLAYER_FOUND.getErrorMsg());
             LoginResultDto loginResultDto = new LoginResultDto();
-            loginResultDto.setToken(token);
-            loginResultDto.setCardNo(loginResultDto.getCardNo());
-            anchorStudioService.startStudio(player,token, loginInfo.getGame());
-
+            if(StringUtils.isNotBlank(loginInfo.getToken())){
+                BzAnchorStudio anchorStudio = anchorStudioService.getByRoomId(loginInfo.getToken());
+                Assert.notNull(anchorStudio, ErrorCode.TOKEN_EXPIRED.getErrorMsg());
+
+                loginResultDto.setToken(loginInfo.getToken());
+                loginResultDto.setCardNo(loginInfo.getCardNo());
+                TokenStatusManager.getInstance().removeSignal(loginInfo.getToken());
+            }else{
+                String toEncode = UUID.randomUUID().toString().concat(String.valueOf(loginInfo.getTimestamp()));
+                String token = EncodeUtils.customBase64Encode(toEncode);
+                stringRedisTemplate.opsForValue().set(TOKEN_PRIFIX.concat(loginInfo.getCardNo()),token);
+
+                loginResultDto.setToken(token);
+                loginResultDto.setCardNo(loginResultDto.getCardNo());
+                anchorStudioService.startStudio(player,token, loginInfo.getGame());
+            }
             return loginResultDto;
         }catch (Exception ex){
             logger.error(String.format("登录失败,账号: %s, 密码: %s",loginInfo.getCardNo(),loginInfo.getCardPwd()),ex);

+ 27 - 4
src/main/java/com/hy/modules/bz/websocket/BarrageWebSocketServer.java

@@ -7,19 +7,23 @@ import com.hy.modules.bz.domain.BzAnchorStudio;
 import com.hy.modules.bz.domain.BzGiftRecord;
 import com.hy.modules.bz.service.IBzAnchorStudioService;
 import com.hy.modules.bz.service.IBzGiftRecordService;
-import com.hy.modules.bz.service.IBzPlayerService;
+import com.hy.modules.bz.utils.TokenStatusManager;
 import com.hy.modules.bz.websocket.message.GiftMessage;
 import com.hy.modules.bz.websocket.message.MessageType;
 import com.hy.modules.sys.domain.SysDictData;
 import com.hy.modules.sys.service.SysDictDataService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.web.socket.WebSocketSession;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import static com.hy.modules.bz.utils.Constants.*;
 
@@ -27,10 +31,11 @@ public class BarrageWebSocketServer extends AbstractWebSocketServer {
 
     private static final String PLATFORM = "tiktok";
 
+    public static final String PATH = "/barrage/war";
+
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
-    @Resource
-    private IBzPlayerService playerService;
+    private static final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(8);
 
     @Resource
     private IBzAnchorStudioService anchorStudioService;
@@ -41,6 +46,13 @@ public class BarrageWebSocketServer extends AbstractWebSocketServer {
     @Resource
     private SysDictDataService sysDictDataService;
 
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Value("${websocket.reconnect.time}")
+    private int reconnectTime;
+
+
     @Override
     public void handleOpen(WebSocketSession session) {
 
@@ -48,12 +60,22 @@ public class BarrageWebSocketServer extends AbstractWebSocketServer {
 
     @Override
     public void handleClose(WebSocketSession session) {
-        anchorStudioService.stopStudio(session.getAttributes().get(TOKEN_PRIFIX).toString());
+        TokenStatusManager.getInstance().sendSignal(session.getAttributes().get(TOKEN_PRIFIX).toString());
+        executor.schedule(() -> {
+            if(TokenStatusManager.getInstance().isInSignal(session.getAttributes().get(TOKEN_PRIFIX).toString())){
+                BzAnchorStudio anchorStudio = anchorStudioService.stopStudio(session.getAttributes().get(TOKEN_PRIFIX).toString());
+                if(null != anchorStudio){
+                    stringRedisTemplate.delete(TOKEN_PRIFIX.concat(anchorStudio.getAnchorName()));
+                }
+            }
+        },reconnectTime, TimeUnit.SECONDS);
+
     }
 
     @Override
     public void handleMessage(String message, WebSocketSession session) {
         JSONObject object = JSON.parseObject(message);
+
         if(MessageType.GiftMessage.equals(MessageType.getMessageType(object.getString(MESSAGE_TYPE_CODE)))){
             // 暂时只处理礼物消息
             GiftMessage giftMessage = JSON.parseObject(message, GiftMessage.class);
@@ -63,6 +85,7 @@ public class BarrageWebSocketServer extends AbstractWebSocketServer {
             saveGiftRecord(giftMessage);
         }
 
+
     }
 
     private BigDecimal getGiftScore(String giftName) throws RuntimeException{

+ 5 - 1
src/main/resources/application.yml

@@ -114,4 +114,8 @@ mybatis-plus:
   ## 日志打印
   configuration:
     ## 日志实现
-    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+websocket:
+  reconnect:
+    time: 7