|
@@ -4,12 +4,15 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import com.zanxiang.erp.base.pojo.TokenInfo;
|
|
|
import com.zanxiang.erp.security.util.SecurityUtil;
|
|
|
import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
|
|
|
+import com.zanxiang.game.module.manage.enums.KfRoomMsgOwnerEnum;
|
|
|
import com.zanxiang.game.module.manage.enums.KfWebSocketMsgEnum;
|
|
|
import com.zanxiang.game.module.manage.pojo.dto.KfWebSocketMsgDTO;
|
|
|
import com.zanxiang.game.module.manage.pojo.params.KfWebSocketMsgParam;
|
|
|
+import com.zanxiang.game.module.manage.service.IKfRoomMsgService;
|
|
|
import com.zanxiang.game.module.manage.service.IKfRoomService;
|
|
|
import com.zanxiang.game.module.manage.service.IKfSessionUserService;
|
|
|
import com.zanxiang.game.module.mybatis.entity.KfRoom;
|
|
|
+import com.zanxiang.game.module.mybatis.entity.KfRoomMsg;
|
|
|
import com.zanxiang.game.module.mybatis.entity.KfSessionUser;
|
|
|
import com.zanxiang.module.util.JsonUtil;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
@@ -22,6 +25,7 @@ import org.springframework.web.socket.CloseStatus;
|
|
|
import org.springframework.web.socket.WebSocketHandler;
|
|
|
import org.springframework.web.socket.WebSocketMessage;
|
|
|
import org.springframework.web.socket.WebSocketSession;
|
|
|
+import reactor.util.function.Tuple2;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.List;
|
|
@@ -49,6 +53,9 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
|
|
|
@Autowired
|
|
|
private IKfSessionUserService kfSessionUserService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private IKfRoomMsgService kfRoomMsgService;
|
|
|
+
|
|
|
/**
|
|
|
* websocket连接建立成功
|
|
|
*/
|
|
@@ -64,52 +71,59 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
|
|
|
String msgStr = message.getPayload().toString();
|
|
|
log.error("收到前端消息 msgStr : {}", msgStr);
|
|
|
//消息解析
|
|
|
- KfWebSocketMsgParam kfWebSocketMsgParam = JsonUtil.toObj(msgStr, KfWebSocketMsgParam.class);
|
|
|
- log.error("收到前端消息解析结果 kfWebSocketMsgParam : {}", JsonUtil.toString(kfWebSocketMsgParam));
|
|
|
+ KfWebSocketMsgParam param = JsonUtil.toObj(msgStr, KfWebSocketMsgParam.class);
|
|
|
+ log.error("收到前端消息解析结果 kfWebSocketMsgParam : {}", JsonUtil.toString(param));
|
|
|
//消息类型
|
|
|
- KfWebSocketMsgEnum webSocketMsgType = kfWebSocketMsgParam.getWebSocketMsgType();
|
|
|
+ KfWebSocketMsgEnum webSocketMsgType = param.getWebSocketMsgType();
|
|
|
+ //游戏id
|
|
|
+ Long gameId = param.getGameId();
|
|
|
//请求令牌
|
|
|
- String token = kfWebSocketMsgParam.getToken();
|
|
|
- //连接身份验证
|
|
|
- boolean tokenCheckResult = this.tokenCheck(webSocketMsgType, token);
|
|
|
- //身份验证失败, 没有后续动作
|
|
|
- if (!tokenCheckResult) {
|
|
|
+ String token = param.getToken();
|
|
|
+ //参数验证
|
|
|
+ boolean checkResult = this.paramCheck(webSocketMsgType, token, gameId);
|
|
|
+ //参数验证失败, 没有后续动作
|
|
|
+ if (!checkResult) {
|
|
|
log.error("token验证失败, token : {}", token);
|
|
|
return;
|
|
|
}
|
|
|
//握手-消息处理
|
|
|
- if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_HAND_SHAKE)) {
|
|
|
+ if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_HAND_SHAKE)) {
|
|
|
log.error("首次握手, kfUserId : {}", SecurityUtil.getUserId());
|
|
|
this.kfHandShake(session, webSocketMsgType);
|
|
|
}
|
|
|
//创建连接-消息处理
|
|
|
- if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_CREATE_CONNECT)) {
|
|
|
- log.error("创建连接, kfUserId : {}", SecurityUtil.getUserId());
|
|
|
- this.kfCreateConnect(webSocketMsgType);
|
|
|
+ if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_CREATE_CONNECT)) {
|
|
|
+ log.error("创建连接, kfUserId : {}, gameId : {}", SecurityUtil.getUserId(), gameId);
|
|
|
+ this.kfCreateConnect(webSocketMsgType, gameId);
|
|
|
}
|
|
|
//玩家接入-消息处理
|
|
|
- if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_USER_CONNECT_JOIN)) {
|
|
|
- log.error("玩家接入, kfUserId : {}", SecurityUtil.getUserId());
|
|
|
- this.userConnectJoin(kfWebSocketMsgParam);
|
|
|
+ if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_USER_CONNECT_JOIN)) {
|
|
|
+ log.error("玩家接入, kfUserId : {}, gameId : {}", SecurityUtil.getUserId(), gameId);
|
|
|
+ this.userConnectJoin(param);
|
|
|
}
|
|
|
//获取房间历史消息-消息处理
|
|
|
- if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_ROOM_HISTORY)) {
|
|
|
- log.error("获取房间历史消息, kfUserId : {}", SecurityUtil.getUserId());
|
|
|
+ if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_ROOM_HISTORY)) {
|
|
|
+ log.error("获取房间历史消息, kfUserId : {}, gameId : {}, roomId : {}",
|
|
|
+ SecurityUtil.getUserId(), param.getGameId(), param.getRoomId());
|
|
|
+ this.msgRoomHistory(param);
|
|
|
}
|
|
|
//客服发送消息-消息处理
|
|
|
- if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_SEND)) {
|
|
|
+ if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_SEND)) {
|
|
|
|
|
|
}
|
|
|
//获取已结束房间列表-消息处理
|
|
|
- if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_FINISH_ROOM_LIST)) {
|
|
|
-
|
|
|
+ if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_FINISH_ROOM_LIST)) {
|
|
|
+ log.error("获取已结束房间列表, kfUserId : {}, gameId : {}", SecurityUtil.getUserId(), param.getGameId());
|
|
|
+ this.finishRoomList(param);
|
|
|
}
|
|
|
//结束会话-消息处理
|
|
|
- if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_FINISH_SESSION)) {
|
|
|
-
|
|
|
+ if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_FINISH_SESSION)) {
|
|
|
+ log.error("结束会话, kfUserId : {}, gameId : {}, roomId : {}",
|
|
|
+ SecurityUtil.getUserId(), param.getGameId(), param.getRoomId());
|
|
|
+ this.kfFinishSession(webSocketMsgType, param.getGameId(), param.getRoomId());
|
|
|
}
|
|
|
//快捷回复-消息处理
|
|
|
- if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_QUICK_REPLY)) {
|
|
|
+ if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_QUICK_REPLY)) {
|
|
|
|
|
|
}
|
|
|
}
|
|
@@ -128,11 +142,6 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
|
|
|
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
|
|
//从session中获取客服id
|
|
|
Long kfUserId = Long.valueOf(session.getAttributes().get("kfUserId").toString());
|
|
|
- //关闭session关联的房间, 有在线状态的更新为断开状态
|
|
|
- kfRoomService.update(new LambdaUpdateWrapper<KfRoom>()
|
|
|
- .set(KfRoom::getOnline, Boolean.FALSE)
|
|
|
- .set(KfRoom::getUpdateTime, LocalDateTime.now())
|
|
|
- .eq(KfRoom::getKfUserId, kfUserId));
|
|
|
//关闭连接
|
|
|
session.close();
|
|
|
//移除连接
|
|
@@ -144,48 +153,108 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ private void kfFinishSession(KfWebSocketMsgEnum webSocketMsgType, Long gameId, Long roomId) {
|
|
|
+ //房间在线状态更新
|
|
|
+ kfRoomService.update(new LambdaUpdateWrapper<KfRoom>()
|
|
|
+ .set(KfRoom::getOnline, Boolean.FALSE)
|
|
|
+ .set(KfRoom::getUpdateTime, LocalDateTime.now())
|
|
|
+ .eq(KfRoom::getId, roomId));
|
|
|
+ //推送完整的已链接房间列表
|
|
|
+ List<KfWebSocketMsgDTO.RoomBean> onlineRoomList = kfRoomService.getOnlineRoomList(gameId);
|
|
|
+ this.pushMessage(KfWebSocketMsgDTO.builder()
|
|
|
+ .webSocketMsgType(webSocketMsgType)
|
|
|
+ .kfUserId(SecurityUtil.getUserId())
|
|
|
+ .gameId(gameId)
|
|
|
+ .roomList(onlineRoomList)
|
|
|
+ .build());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void finishRoomList(KfWebSocketMsgParam param) {
|
|
|
+ Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomBean>> tuple2 = kfRoomService
|
|
|
+ .getFinishRoomList(param.getGameId(), param.getPage());
|
|
|
+ this.pushMessage(KfWebSocketMsgDTO.builder()
|
|
|
+ .webSocketMsgType(param.getWebSocketMsgType())
|
|
|
+ .kfUserId(SecurityUtil.getUserId())
|
|
|
+ .gameId(param.getGameId())
|
|
|
+ .page(tuple2.getT1())
|
|
|
+ .roomList(tuple2.getT2())
|
|
|
+ .build());
|
|
|
+ }
|
|
|
+
|
|
|
private void msgRoomHistory(KfWebSocketMsgParam param) {
|
|
|
- if (param.getRoomId() == null || param.getPage() == null) {
|
|
|
- this.pushMessage(KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
|
|
|
- "获取房间历史消息参数错误, roomId和page都不可为空, param : " + JsonUtil.toString(param)));
|
|
|
+ if (param.getRoomId() == null) {
|
|
|
+ this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), param.getWebSocketMsgType(),
|
|
|
+ "获取房间历史消息参数错误, roomId不可为空, param : " + JsonUtil.toString(param)));
|
|
|
}
|
|
|
+ //当获取第一页的时候, 房间未读消息全部更新成已读消息
|
|
|
+ if (param.getPage().getPageNum() == 1) {
|
|
|
+ kfRoomMsgService.update(new LambdaUpdateWrapper<KfRoomMsg>()
|
|
|
+ .set(KfRoomMsg::getReadStatus, Boolean.TRUE)
|
|
|
+ .set(KfRoomMsg::getUpdateTime, LocalDateTime.now())
|
|
|
+ .eq(KfRoomMsg::getRoomId, param.getRoomId()));
|
|
|
+ }
|
|
|
+ //分页获取房间消息列表
|
|
|
+ Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomMsgBean>> tuple2 = kfRoomMsgService
|
|
|
+ .msgRoomHistory(param.getRoomId(), param.getPage());
|
|
|
+ this.pushMessage(KfWebSocketMsgDTO.builder()
|
|
|
+ .webSocketMsgType(param.getWebSocketMsgType())
|
|
|
+ .kfUserId(SecurityUtil.getUserId())
|
|
|
+ .page(tuple2.getT1())
|
|
|
+ .gameId(param.getGameId())
|
|
|
+ .roomId(param.getRoomId())
|
|
|
+ .roomMsgList(tuple2.getT2())
|
|
|
+ .build());
|
|
|
}
|
|
|
|
|
|
private void userConnectJoin(KfWebSocketMsgParam param) {
|
|
|
- if (Strings.isBlank(param.getOpenId()) || param.getGameId() == null) {
|
|
|
- this.pushMessage(KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
|
|
|
+ if (Strings.isBlank(param.getOpenId())) {
|
|
|
+ this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), param.getWebSocketMsgType(),
|
|
|
"接入玩家参数错误, openId和gameId都不可为空, param : " + JsonUtil.toString(param)));
|
|
|
}
|
|
|
+ //todo : 判断玩家是否已被接入
|
|
|
+
|
|
|
+
|
|
|
//玩家更新
|
|
|
kfSessionUserService.update(new LambdaUpdateWrapper<KfSessionUser>()
|
|
|
.set(KfSessionUser::getIsWait, Boolean.FALSE)
|
|
|
.set(KfSessionUser::getUpdateTime, LocalDateTime.now()));
|
|
|
//房间更新
|
|
|
- kfRoomService.userJoinRoom(param.getOpenId(), param.getGameId());
|
|
|
+ Long roomId = kfRoomService.userJoinRoom(param.getOpenId(), param.getGameId());
|
|
|
+ //玩家未读消息更新到房间
|
|
|
+ kfRoomMsgService.update(new LambdaUpdateWrapper<KfRoomMsg>()
|
|
|
+ .set(KfRoomMsg::getRoomId, roomId)
|
|
|
+ .set(KfRoomMsg::getUpdateTime, LocalDateTime.now())
|
|
|
+ .eq(KfRoomMsg::getOpenId, param.getOpenId())
|
|
|
+ .eq(KfRoomMsg::getGameId, param.getGameId())
|
|
|
+ .ne(KfRoomMsg::getMsgOwner, KfRoomMsgOwnerEnum.KF_MSG_OWNER_KF.getValue())
|
|
|
+ .eq(KfRoomMsg::getReadStatus, Boolean.FALSE));
|
|
|
//发送消息, 给该客服返回完整的已接入房间列表
|
|
|
- List<KfWebSocketMsgDTO.RoomBean> roomList = kfRoomService.getOnlineRoomList();
|
|
|
+ List<KfWebSocketMsgDTO.RoomBean> roomList = kfRoomService.getOnlineRoomList(param.getGameId());
|
|
|
this.pushMessage(KfWebSocketMsgDTO.builder()
|
|
|
.webSocketMsgType(param.getWebSocketMsgType())
|
|
|
.kfUserId(SecurityUtil.getUserId())
|
|
|
+ .gameId(param.getGameId())
|
|
|
.roomList(roomList)
|
|
|
.build());
|
|
|
//发送消息, 给所有在线客服推送完整待接入列表
|
|
|
- List<KfWebSocketMsgDTO.WaitUserBean> waitUserList = kfSessionUserService.getWaitUserList();
|
|
|
+ List<KfWebSocketMsgDTO.WaitUserBean> waitUserList = kfSessionUserService.getWaitUserList(param.getGameId());
|
|
|
this.pushMessage(KfWebSocketMsgDTO.builder()
|
|
|
.webSocketMsgType(param.getWebSocketMsgType())
|
|
|
+ .gameId(param.getGameId())
|
|
|
.waitUserList(waitUserList)
|
|
|
.build());
|
|
|
}
|
|
|
|
|
|
- private void kfCreateConnect(KfWebSocketMsgEnum msgTypeEnum) {
|
|
|
+ private void kfCreateConnect(KfWebSocketMsgEnum msgTypeEnum, Long gameId) {
|
|
|
//获取待接入列表
|
|
|
- List<KfWebSocketMsgDTO.WaitUserBean> waitUserList = kfSessionUserService.getWaitUserList();
|
|
|
+ List<KfWebSocketMsgDTO.WaitUserBean> waitUserList = kfSessionUserService.getWaitUserList(gameId);
|
|
|
//获取已接入房间列表
|
|
|
- List<KfWebSocketMsgDTO.RoomBean> roomList = kfRoomService.getOnlineRoomList();
|
|
|
+ List<KfWebSocketMsgDTO.RoomBean> roomList = kfRoomService.getOnlineRoomList(gameId);
|
|
|
//发送消息
|
|
|
this.pushMessage(KfWebSocketMsgDTO.builder()
|
|
|
.webSocketMsgType(msgTypeEnum)
|
|
|
.kfUserId(SecurityUtil.getUserId())
|
|
|
+ .gameId(gameId)
|
|
|
.waitUserList(waitUserList)
|
|
|
.roomList(roomList)
|
|
|
.build());
|
|
@@ -206,16 +275,22 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
|
|
|
.build());
|
|
|
}
|
|
|
|
|
|
- private boolean tokenCheck(KfWebSocketMsgEnum webSocketMsgType, String token) {
|
|
|
+ private boolean paramCheck(KfWebSocketMsgEnum webSocketMsgType, String token, Long gameId) {
|
|
|
//令牌为空
|
|
|
if (Strings.isBlank(token)) {
|
|
|
- this.pushMessage(KfWebSocketMsgDTO.fail(webSocketMsgType, "非法参数, token令牌不可为空"));
|
|
|
+ this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), webSocketMsgType, "非法参数, token令牌不可为空"));
|
|
|
return Boolean.FALSE;
|
|
|
}
|
|
|
//令牌验证
|
|
|
TokenInfo tokenInfo = SecurityUtil.parseToken(token);
|
|
|
if (tokenInfo == null) {
|
|
|
- this.pushMessage(KfWebSocketMsgDTO.fail(webSocketMsgType, "参数错误, 令牌验证不通过"));
|
|
|
+ this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), webSocketMsgType, "参数错误, 令牌验证不通过"));
|
|
|
+ return Boolean.FALSE;
|
|
|
+ }
|
|
|
+ //非首次握手, 校验gameId参数
|
|
|
+ if (!Objects.equals(KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_HAND_SHAKE, webSocketMsgType)
|
|
|
+ && gameId == null) {
|
|
|
+ this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), webSocketMsgType, "参数错误, gameId为空"));
|
|
|
return Boolean.FALSE;
|
|
|
}
|
|
|
//将token设置到当前线程
|