diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/chat/ChatManager.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/chat/ChatManager.java index 0a3c7bf7..5c9ca743 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/chat/ChatManager.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/chat/ChatManager.java @@ -20,6 +20,7 @@ import com.ruoyi.cai.ws.bean.Room; import com.ruoyi.cai.ws.constant.RedisConstant; import com.ruoyi.cai.ws.dto.WsToken; import com.ruoyi.cai.ws.manager.WebSocketManager; +import com.ruoyi.cai.ws.util.MapGetUtil; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.helper.LoginHelper; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +31,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; @@ -56,14 +58,29 @@ public class ChatManager { String token = IdManager.nextIdStr(); String tokenKey = String.format(RedisConstant.WS_TOKEN, token); Map map = new HashMap<>(); - map.put("userId",userId); map.put("roomId",roomId); map.put("fromUid",fromUid); map.put("toUid",toUid); + map.put("userId",userId); redisTemplate.opsForHash().putAll(tokenKey,map); + redisTemplate.expire(tokenKey,1, TimeUnit.DAYS); return token; } + public WsToken getToken(String token){ + String tokenKey = String.format(RedisConstant.WS_TOKEN, token); + Map entries = redisTemplate.opsForHash().entries(tokenKey); + if(entries.isEmpty()){ + return null; + } + WsToken wsToken = new WsToken(); + wsToken.setRoomId(MapGetUtil.getLong(entries.get("roomId"))); + wsToken.setFromUid(MapGetUtil.getLong(entries.get("fromUid"))); + wsToken.setToUid(MapGetUtil.getLong(entries.get("toUid"))); + wsToken.setUserId(MapGetUtil.getLong(entries.get("userId"))); + return wsToken; + } + public CallResp call(CallReq callReq){ Long userId = LoginHelper.getUserId(); User fromUser = userService.getById(userId); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/bean/RoomData.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/bean/RoomData.java index 3d8c683b..96204340 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/bean/RoomData.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/bean/RoomData.java @@ -13,11 +13,11 @@ public class RoomData { private BigDecimal videoDivide; private Long payCoin = 0L; private Long payIncome = 0L; - private Long hangUpTime; + private Long hangUpTime; // 掉线时间 - private Long settleTime; + private Long settleTime; // 结算时间 - private Long beginTime; + private Long beginTime; // 开始时间 private boolean releaseRes = false; } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/bean/UserData.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/bean/UserData.java index fe43b36b..86e46be1 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/bean/UserData.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/bean/UserData.java @@ -12,4 +12,5 @@ public class UserData { private String nickname; private String userCode; private Long connectTime; + private Long heartTime; } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/FdCtxDataCache.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/FdCtxDataCache.java index 856d1fee..6d981914 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/FdCtxDataCache.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/FdCtxDataCache.java @@ -11,6 +11,13 @@ import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; +/** + * key :sessionKey + * value : 当前用户信息 + * 一个call 有两个redis + *

created on 2024/1/11 22:44

+ * @author duet + */ @Component public class FdCtxDataCache { @Autowired diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/RoomCtxCache.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/RoomCtxCache.java index af6cd2cb..a77460c5 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/RoomCtxCache.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/RoomCtxCache.java @@ -12,6 +12,12 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +/** + * key : 房间号 + * value: { sessionKey : 用户类型 } + *

created on 2024/1/11 22:45

+ * @author duet + */ @Component public class RoomCtxCache { @Autowired @@ -23,7 +29,7 @@ public class RoomCtxCache { public void addFd(String sessionKey,Long roomId,Integer userType){ String key = getKey(roomId); - redisTemplate.opsForHash().putIfAbsent(key,sessionKey,userType); + redisTemplate.opsForHash().put(key,sessionKey,userType); redisTemplate.expire(key,7, TimeUnit.DAYS); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/RoomDataCache.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/RoomDataCache.java index ec3aca07..a3c5bb0b 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/RoomDataCache.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/RoomDataCache.java @@ -20,6 +20,12 @@ import java.util.Arrays; import java.util.Collections; import java.util.Map; +/** + * 房间信息 + * 在拨打电话的时候就已经提前初始化 + *

created on 2024/1/11 22:49

+ * @author duet + */ @Component public class RoomDataCache { @Autowired diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/UserDataCache.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/UserDataCache.java index 345a46ba..cc8da757 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/UserDataCache.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/cache/UserDataCache.java @@ -10,6 +10,11 @@ import org.springframework.stereotype.Component; import java.util.Map; +/** + * 房间的用户信息 拨打电话前就已经创建好 + *

created on 2024/1/11 22:50

+ * @author duet + */ @Component public class UserDataCache { @Autowired diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/config/WebSocketConfig.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/config/WebSocketConfig.java index f8c24e06..8b1949f0 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/config/WebSocketConfig.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/config/WebSocketConfig.java @@ -28,11 +28,9 @@ public class WebSocketConfig { if (StrUtil.isBlank(webSocketProperties.getPath())) { webSocketProperties.setPath("/ws"); } - if (StrUtil.isBlank(webSocketProperties.getAllowedOrigins())) { webSocketProperties.setAllowedOrigins("*"); } - return registry -> registry .addHandler(webSocketHandler, webSocketProperties.getPath()) .addInterceptors(handshakeInterceptor) diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/dto/WsToken.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/dto/WsToken.java index 3fbc60c8..72b0f058 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/dto/WsToken.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/dto/WsToken.java @@ -7,4 +7,13 @@ public class WsToken { private Long roomId; private Long fromUid; private Long toUid; + private Long userId; + + public boolean isCall(){ + return userId.equals(fromUid); + } + + public boolean isReceive(){ + return userId.equals(toUid); + } } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/RoomWebSocketHandler.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/RoomWebSocketHandler.java index 41b3f9ac..26dfd12d 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/RoomWebSocketHandler.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/RoomWebSocketHandler.java @@ -1,15 +1,18 @@ package com.ruoyi.cai.ws.handler; +import com.ruoyi.cai.chat.ChatManager; import com.ruoyi.cai.ws.constant.WebSocketConstants; import com.ruoyi.cai.ws.holder.WebSocketSessionHolder; import com.ruoyi.cai.ws.processon.OpenLogic; import com.ruoyi.cai.ws.util.WebSocketUtils; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.socket.*; import org.springframework.web.socket.handler.AbstractWebSocketHandler; +import javax.websocket.server.PathParam; import java.util.Map; /** @@ -29,13 +32,9 @@ public class RoomWebSocketHandler extends AbstractWebSocketHandler { * 连接成功后 */ @Override - public void afterConnectionEstablished(WebSocketSession session) { - Map attributes = session.getAttributes(); - if(attributes.get("token") != null){ - WebSocketSessionHolder.addSession(attributes.get("token").toString(), session); - } + public void afterConnectionEstablished(@NotNull WebSocketSession session) { openLogic.processOn(session); - log.info("[connect] sessionId: {},userId:{}", session.getId(), session.getId()); +// log.info("[connect] sessionId: {},userId:{}", session.getId(), session.getId()); } /** diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/GiftMessageHandler.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/GiftMessageHandler.java index b6e8ce4d..bed99b8d 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/GiftMessageHandler.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/handler/message/GiftMessageHandler.java @@ -3,7 +3,9 @@ package com.ruoyi.cai.ws.handler.message; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.cai.domain.Account; import com.ruoyi.cai.domain.Gift; +import com.ruoyi.cai.dto.ConsumeResp; import com.ruoyi.cai.dto.app.query.GiveGiftRes; +import com.ruoyi.cai.manager.ConsumerManager; import com.ruoyi.cai.service.AccountService; import com.ruoyi.cai.service.GiftService; import com.ruoyi.cai.service.UserGiftService; @@ -23,6 +25,8 @@ public class GiftMessageHandler extends AbstractMessageHandle implements IMessag private AccountService accountService; @Autowired private UserGiftService userGiftService; + @Autowired + private ConsumerManager consumerManager; @Override public void processOn(Room room, FdCtxData fdCtxData, JSONObject map) { Long giftId = map.getLong("giftId"); @@ -50,8 +54,8 @@ public class GiftMessageHandler extends AbstractMessageHandle implements IMessag giveGiftRes.setToUserId(fdCtxData.getTarUserId()); giveGiftRes.setGiftId(giftId); giveGiftRes.setGiftCount(giftCount); - boolean b = userGiftService.giveGift(giveGiftRes); - if(!b){ + ConsumeResp consumeResp = consumerManager.sendGift(giveGiftRes); + if(!consumeResp.isSuccess()){ sendToCurrent(fdCtxData,WsRMsgGen.sysNotice("赠送失败,请重试")); return; } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/manager/WebSocketManager.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/manager/WebSocketManager.java index b9cb48b1..194e08da 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/manager/WebSocketManager.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/manager/WebSocketManager.java @@ -97,8 +97,6 @@ public class WebSocketManager { // 检查女神在线状态 TODO // 关闭发起的其他房间 - - roomService.closeAllRoom(call.getFromUid()); // 删除旧房间记录 roomService.delCallRoom(call.getFromUid()); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/processon/OpenLogic.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/processon/OpenLogic.java index 4ebd0b6d..8069caea 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/processon/OpenLogic.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/processon/OpenLogic.java @@ -1,10 +1,11 @@ package com.ruoyi.cai.ws.processon; import cn.hutool.core.date.DateUtil; -import com.ruoyi.cai.trd.Agora; +import com.ruoyi.cai.chat.ChatManager; import com.ruoyi.cai.executor.ExecutorConstant; import com.ruoyi.cai.service.AnchorService; import com.ruoyi.cai.service.UserService; +import com.ruoyi.cai.trd.Agora; import com.ruoyi.cai.ws.bean.FdCtxData; import com.ruoyi.cai.ws.bean.Room; import com.ruoyi.cai.ws.cache.*; @@ -12,16 +13,21 @@ import com.ruoyi.cai.ws.constant.HangUpEnums; import com.ruoyi.cai.ws.constant.RoomStatusEnums; import com.ruoyi.cai.ws.constant.UserDataConstant; import com.ruoyi.cai.ws.dto.WsRMsgGen; +import com.ruoyi.cai.ws.dto.WsToken; +import com.ruoyi.cai.ws.holder.WebSocketSessionHolder; import com.ruoyi.cai.ws.service.CheckConnectionDTO; import com.ruoyi.cai.ws.service.RoomService; -import com.ruoyi.cai.ws.util.MapGetUtil; import com.ruoyi.cai.ws.util.RoomWebSocketUtil; +import com.ruoyi.cai.ws.util.TimeConverter; import com.ruoyi.cai.ws.util.WsExceptionUtil; +import com.ruoyi.yunxin.Yunxin; +import com.ruoyi.yunxin.data.SendAttachMsgData; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketSession; +import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -46,37 +52,39 @@ public class OpenLogic { private AnchorService anchorService; @Autowired private Agora agora; + @Autowired + private ChatManager chatManager; + @Autowired + private Yunxin yunxin; - public void processOn(WebSocketSession session) { - Map map = session.getAttributes(); - String token = MapGetUtil.getString(map.get("token")); - Long roomId = MapGetUtil.getLong(map.get("roomId")); - Long userId = MapGetUtil.getLong(map.get("userId")); - // 校验token - process(token,roomId,userId); - } - - public void process(String sessionKey,Long roomId,Long userId){ + public void processOn(WebSocketSession session) throws IOException { + Map attributes = session.getAttributes(); + Object token = attributes.get("token"); + if(token == null){ + WsExceptionUtil.throwExceptionFast(session,"参数异常"); + return; + } + WsToken wsToken = chatManager.getToken(String.valueOf(token)); + if(wsToken == null){ + WsExceptionUtil.throwExceptionFast(session,"无效token"); + return; + } + WebSocketSessionHolder.addSession(session.getId(), session); + Long roomId = wsToken.getRoomId(); + Long userId = wsToken.getUserId(); Room room = roomService.load(roomId); if(room == null || (room.getCallUserData().getId().equals(userId) && room.getReceiverUserData().getId().equals(userId))){ - WsExceptionUtil.throwException(sessionKey,"房间不可用", HangUpEnums.OTHER,roomId); + WsExceptionUtil.throwException(session,"房间不可用", HangUpEnums.OTHER,roomId); return; } CheckConnectionDTO checkConnect = roomService.checkConnect(room); if(checkConnect != null){ - WsExceptionUtil.throwException(sessionKey,checkConnect.getMessage(),checkConnect.getHangUpEnums(),roomId); + WsExceptionUtil.throwException(session,checkConnect.getMessage(),checkConnect.getHangUpEnums(),roomId); return; } - if(userId.equals(room.getCallUserData().getId())){ - // 走主叫方逻辑 - callerConnection(sessionKey,room,userId); - }else { - // 走接收方逻辑 - receiverConnection(sessionKey,room,userId); - } // 保存上下文到redis FdCtxData fdCtxData = new FdCtxData(); - fdCtxData.setSessionKey(sessionKey); + fdCtxData.setSessionKey(session.getId()); fdCtxData.setRoomId(room.getRoomId()); fdCtxData.setUserId(userId); if(userId.equals(room.getCallUserData().getId())){ @@ -89,10 +97,18 @@ public class OpenLogic { fdCtxData.setTarUserType(UserDataConstant.TYPE_CALLER); } fdCtxDataCache.save(fdCtxData); - roomCtxCache.addFd(sessionKey,roomId,fdCtxData.getUserType()); + roomCtxCache.addFd(session.getId(),roomId,fdCtxData.getUserType()); + if(userId.equals(room.getCallUserData().getId())){ + // 走主叫方逻辑 + callerConnection(session,room,userId); + }else { + // 走接收方逻辑 + receiverConnection(session,room,userId); + } + } - public void callerConnection(String sessionKey,Room room,Long userId){ + public void callerConnection(WebSocketSession session,Room room,Long userId){ boolean isFirst = false; Integer status = room.getStatus(); // 首次链接 @@ -110,17 +126,18 @@ public class OpenLogic { // 已经接通 if(room.isOnline()){ ExecutorConstant.ROOM_EXECUTOR.execute(() -> { + // 已经接通,看一下是否掉线了,为重连 // 如果视频也掉线了,则重连的时候发送消息提示 List channelUsers = agora.getChannelUsers(room.getRoomId()); if(channelUsers.contains(userId+"")){ return; } Long callTime = roomService.getCallTime(room); - RoomWebSocketUtil.sendSendMessage(sessionKey, WsRMsgGen.startVideo(room.getRoomId(), callTime)); - RoomWebSocketUtil.sendSendMessage(sessionKey,WsRMsgGen.sysNotice("重连成功,房间已通话(转换成时分秒) ")); + RoomWebSocketUtil.sendSendMessage(session, WsRMsgGen.startVideo(room.getRoomId(), callTime)); + RoomWebSocketUtil.sendSendMessage(session,WsRMsgGen.sysNotice("重连成功,房间已通话 "+ TimeConverter.convertSecondsToHMS(callTime))); String sessionKeyReceiver = roomCtxCache.getSessionKeyReceiverByRoomId(room.getRoomId()); if(StringUtils.isNotEmpty(sessionKeyReceiver)){ - RoomWebSocketUtil.sendSendMessage(sessionKey,WsRMsgGen.sysNotice("对方已重连成功")); + RoomWebSocketUtil.sendSendMessage(session,WsRMsgGen.sysNotice("对方已重连成功")); } }); } @@ -128,13 +145,19 @@ public class OpenLogic { RoomStatusEnums.STATUS_CALLER_CONNECT.getCode().equals(status) || RoomStatusEnums.STATUS_RECEIVER_CONNECT.getCode().equals(status)){ // 给当前会话发送消息 - 连线成功 - RoomWebSocketUtil.sendSendMessage(sessionKey, WsRMsgGen.response(room.getRoomId())); + RoomWebSocketUtil.sendSendMessage(session, WsRMsgGen.response(room.getRoomId())); } if(isFirst){ - // 给对方发送呼叫页面 TODO + ExecutorConstant.ROOM_EXECUTOR.execute(() -> { + // 给对方发送呼叫页面 + ; + SendAttachMsgData msg = SendAttachMsgData.init(room.getRoomId()); + yunxin.sendAttachMsg(room.getCallUserData().getId(), + room.getReceiverUserData().getId(), msg); + }); } } - public void receiverConnection(String sessionKey,Room room,Long userId){ + public void receiverConnection(WebSocketSession session,Room room,Long userId){ Integer status = room.getStatus(); // 首次链接 if(RoomStatusEnums.STATUS_CALLER_CONNECT.getCode().equals(status)){ @@ -143,6 +166,7 @@ public class OpenLogic { map.put("connectTime", DateUtil.currentSeconds()); map.put("heartTime",DateUtil.currentSeconds()); userDataCache.hMSet(room.getRoomId(), UserDataConstant.TYPE_RECEIVER,map); + // 房间号状态设置为 接收方已连接 boolean res = roomDataCache.setStatusReceiverConnection(room.getRoomId()); if(!res){ return; @@ -150,8 +174,8 @@ public class OpenLogic { userService.updateVideoStatus(userId,1); anchorService.updateVideoStatus(userId,1); } - RoomWebSocketUtil.sendSendMessage(sessionKey, WsRMsgGen.response(room.getRoomId())); - RoomWebSocketUtil.sendSendMessage(sessionKey, WsRMsgGen.updateTip()); + RoomWebSocketUtil.sendSendMessage(session, WsRMsgGen.response(room.getRoomId())); + RoomWebSocketUtil.sendSendMessage(session, WsRMsgGen.updateTip()); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/RoomWebSocketUtil.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/RoomWebSocketUtil.java index af7fd756..eddecdf2 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/RoomWebSocketUtil.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/RoomWebSocketUtil.java @@ -2,6 +2,7 @@ package com.ruoyi.cai.ws.util; import com.alibaba.fastjson2.JSON; import com.ruoyi.cai.ws.dto.WsR; +import org.springframework.web.socket.WebSocketSession; import java.util.List; @@ -10,6 +11,10 @@ public class RoomWebSocketUtil { WebSocketUtils.sendMessage(sessionKey, JSON.toJSONString(r)); } + public static void sendSendMessage(WebSocketSession sessionKey, WsR r){ + WebSocketUtils.sendMessage(sessionKey, JSON.toJSONString(r)); + } + public static void sendSendMessage(List sessionKey, WsR r){ for (String s : sessionKey) { WebSocketUtils.sendMessage(s, JSON.toJSONString(r)); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/TimeConverter.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/TimeConverter.java new file mode 100644 index 00000000..6eb444a6 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/TimeConverter.java @@ -0,0 +1,10 @@ +package com.ruoyi.cai.ws.util; + +public class TimeConverter { + public static String convertSecondsToHMS(Long seconds){ + long hours = seconds / 3600; + long minutes = (seconds % 3600) / 60; + long secondsShow = seconds % 60; + return hours + ":" + minutes + ":" + secondsShow; + } +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/WebSocketUtils.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/WebSocketUtils.java index a3756279..0827fc09 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/WebSocketUtils.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/WebSocketUtils.java @@ -33,12 +33,16 @@ public class WebSocketUtils { public static boolean close(String sessionKey) { WebSocketSession sessions = WebSocketSessionHolder.getSessions(sessionKey); - if(sessions != null){ + return close(sessions); + } + + public static boolean close(WebSocketSession session) { + if(session != null){ try { - sessions.close(); + session.close(); return true; } catch (IOException e) { - log.error("关闭ws失败,sessionKey={}",sessionKey,e); + log.error("关闭ws失败,session={}",session,e); } } return false; diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/WsExceptionUtil.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/WsExceptionUtil.java index 687ba03c..f3480ce2 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/WsExceptionUtil.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/ws/util/WsExceptionUtil.java @@ -3,6 +3,9 @@ package com.ruoyi.cai.ws.util; import com.ruoyi.cai.ws.constant.HangUpEnums; import com.ruoyi.cai.ws.dto.WsRMsgGen; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.socket.WebSocketSession; + +import java.io.IOException; @Slf4j public class WsExceptionUtil { @@ -15,6 +18,25 @@ public class WsExceptionUtil { if(!close){ log.warn("ws连接时发现异常:{},sessionKey {} roomid {}", message, sessionKey, roomId); } + } + public static void throwException(WebSocketSession sessionKey, String message, HangUpEnums hangUpType, Long roomId){ + if(hangUpType == null){ + hangUpType = HangUpEnums.OTHER; + } + RoomWebSocketUtil.sendSendMessage(sessionKey, WsRMsgGen.hangup(message,roomId,hangUpType.getCode())); + boolean close = WebSocketUtils.close(sessionKey); + if(!close){ + log.warn("ws连接时发现异常:{},sessionKey {} roomid {}", message, sessionKey, roomId); + } + } + + public static void throwExceptionFast(WebSocketSession session,String message){ + RoomWebSocketUtil.sendSendMessage(session, WsRMsgGen.hangup(message, null, HangUpEnums.OTHER.getCode())); + try { + session.close(); + } catch (IOException e) { + log.error("快速关闭ws 失败",e); + } } } diff --git a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/Yunxin.java b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/Yunxin.java index df738343..df40f79d 100644 --- a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/Yunxin.java +++ b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/Yunxin.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON; import com.ruoyi.yunxin.client.ImMessageClient; import com.ruoyi.yunxin.config.YunxinProperties; import com.ruoyi.yunxin.req.Option; +import com.ruoyi.yunxin.req.SendAttachMsgReq; import com.ruoyi.yunxin.req.SendBatchMsgReq; import com.ruoyi.yunxin.req.SendMsgReq; import com.ruoyi.yunxin.req.type.YxTextData; @@ -25,7 +26,6 @@ public class Yunxin { @Resource private ImMessageClient messageClient; - @Deprecated public YxDataR sendTo(Long toUid,Long fromUid,Object data){ SendMsgReq req = new SendMsgReq(); req.setFrom(fromUid == null ? yunxinProperties.getDefaultFromUid() : fromUid+""); @@ -44,4 +44,13 @@ public class Yunxin { return messageClient.sendBatchMsg(req); } + public YxDataR sendAttachMsg(Long fromUid, Long toUid, Object data){ + SendAttachMsgReq sendAttachMsgReq = new SendAttachMsgReq(); + sendAttachMsgReq.setFrom(fromUid+""); + sendAttachMsgReq.setTo(toUid+""); + sendAttachMsgReq.setAttach(JSON.toJSONString(data)); + sendAttachMsgReq.setOption(JSON.toJSONString(new Option())); + return messageClient.sendAttachMsg(sendAttachMsgReq); + } + } diff --git a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/client/ImMessageClient.java b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/client/ImMessageClient.java index 0b8467bf..9b5a9a43 100644 --- a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/client/ImMessageClient.java +++ b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/client/ImMessageClient.java @@ -1,8 +1,10 @@ package com.ruoyi.yunxin.client; import com.dtflys.forest.annotation.BaseRequest; +import com.dtflys.forest.annotation.Body; import com.dtflys.forest.annotation.Post; import com.ruoyi.yunxin.interceptor.GlodonTokenInterceptor; +import com.ruoyi.yunxin.req.SendAttachMsgReq; import com.ruoyi.yunxin.req.SendBatchMsgReq; import com.ruoyi.yunxin.req.SendMsgReq; import com.ruoyi.yunxin.resp.SendMsgResp; @@ -12,14 +14,24 @@ import com.ruoyi.yunxin.resp.YxDataR; @BaseRequest(baseURL = "${baseUrl}", interceptor = GlodonTokenInterceptor.class) public interface ImMessageClient { + /** + * 发送自定义消息 + * @param req + * @return + */ @Post(url = "/nimserver/msg/sendMsg.action") - YxDataR sendMsg(SendMsgReq req); + YxDataR sendMsg(@Body SendMsgReq req); @Post(url = "/nimserver/msg/sendBatchMsg.action") - YxDataR sendBatchMsg(SendBatchMsgReq req); + YxDataR sendBatchMsg(@Body SendBatchMsgReq req); -// @Post(url = "/nimserver/msg/sendAttachMsg.action") -// YxR sendAttachMsg(SendMsgReq req); + /** + * 发送自定义系统消息 + * @param req + * @return + */ + @Post(url = "/nimserver/msg/sendAttachMsg.action") + YxDataR sendAttachMsg(@Body SendAttachMsgReq req); } diff --git a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/data/SendAttachMsgData.java b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/data/SendAttachMsgData.java new file mode 100644 index 00000000..b9f3d403 --- /dev/null +++ b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/data/SendAttachMsgData.java @@ -0,0 +1,33 @@ +package com.ruoyi.yunxin.data; + +import cn.hutool.core.date.DateUtil; +import lombok.Data; + +/** + * 系统消息通知 + */ +@Data +public class SendAttachMsgData { + private Long id = 11L; + private SendAttachMsgDataMsg data; + + @Data + public static class SendAttachMsgDataMsg { + private Long amount; + private Long callTime = DateUtil.currentSeconds(); + private Long giftTotal = 0L; + private Long id = 0L; + private Integer linkType = 0; + private Long time = 0L; + private Long toid = 0L; + private Long roomId; + } + + public static SendAttachMsgData init(Long roomId){ + SendAttachMsgData data = new SendAttachMsgData(); + SendAttachMsgDataMsg msgDataMsg = new SendAttachMsgDataMsg(); + msgDataMsg.setRoomId(roomId); + data.setData(msgDataMsg); + return data; + } +} diff --git a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/req/SendAttachMsgReq.java b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/req/SendAttachMsgReq.java index 886cca8e..61ba7ade 100644 --- a/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/req/SendAttachMsgReq.java +++ b/ruoyi-yunxin/src/main/java/com/ruoyi/yunxin/req/SendAttachMsgReq.java @@ -4,5 +4,9 @@ import lombok.Data; @Data public class SendAttachMsgReq { - + private String from; + private Integer msgType = 0; + private String to; + private String attach; + private String option; }