소스 검색

Merge branch 'saas' of http://git.dayaedu.com/yonge/mec into zouxuan_activity_2022-06-09

zouxuan 3 년 전
부모
커밋
86a4c92a5d

+ 107 - 47
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomServiceImpl.java

@@ -92,19 +92,23 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
     public static final String ROOM_UID = "${roomUid}";
 
     //直播间累计用户信息-指只要进入到该房间的用户都要记录
-    public static final String LIVE_ROOM_TOTAL_USER_LIST = "IM:LIVE_ROOM_TOTAL_USER_LIST:" + ROOM_UID;
+    public static final String LIVE_ROOM_TOTAL_USER_LIST = String.join(":", "IM:LIVE_ROOM_TOTAL_USER_LIST", ROOM_UID);
     //直播间在线用户信息
-    public static final String LIVE_ROOM_ONLINE_USER_LIST = "IM:LIVE_ROOM_ONLINE_USER_LIST:" + ROOM_UID;
-    //主讲人信息
-    public static final String LIVE_SPEAKER_INFO = "IM:LIVE_SPEAKER_INFO:" + USER_ID;
-    //用户对应的直播间Uid
-    public static final String LIVE_USER_ROOM = "IM:LIVE_ROOM_USER:" + USER_ID;
-    //记录人员最后变更的状态消息时间
-    public static final String LIVE_USER_STATE_TIME = "IM:LIVE_USER_STATE_TIME:" + USER_ID;
+    public static final String LIVE_ROOM_ONLINE_USER_LIST = String.join(":", "IM:LIVE_ROOM_ONLINE_USER_LIST", ROOM_UID);
+    //当前房间主讲人心跳
+    public static final String LIVE_ROOM_SPEAKER_HEART_BEAT = String.join(":", "IM:LIVE_ROOM_SPEAKER_HEART_BEAT", ROOM_UID);
     //房间点赞数
-    public static final String LIVE_ROOM_LIKE = "IM:LIVE_ROOM_LIKE:" + ROOM_UID;
+    public static final String LIVE_ROOM_LIKE = String.join(":", "IM:LIVE_ROOM_LIKE", ROOM_UID);
     //计算人员观看时长锁
-    public static final String LIVE_LOOK_LOCK = "IM:LIVE_LOOK_LOCK:" + ROOM_UID;
+    public static final String LIVE_LOOK_LOCK = String.join(":", "IM:LIVE_LOOK_LOCK", ROOM_UID);
+    //用户对应的直播间Uid
+    public static final String LIVE_USER_ROOM = String.join(":", "IM:LIVE_ROOM_USER", USER_ID);
+    //记录人员最后变更的状态消息时间
+    public static final String LIVE_USER_STATE_TIME = String.join(":", "IM:LIVE_USER_STATE_TIME", USER_ID);
+    //主讲人信息
+    public static final String LIVE_SPEAKER_INFO = String.join(":", "IM:LIVE_SPEAKER_INFO", ROOM_UID, USER_ID);
+    //主讲人最近一次加入房间的clientIp
+    public static final String LIVE_SPEAKER_LAST_CLIENT_IP = String.join(":", "IM:LIVE_SPEAKER_LAST_CLIENT_IP", ROOM_UID, USER_ID);
     //直播提前开始时间
     public static final int PRE_LIVE_TIME_MINUTE = 30;
 
@@ -198,14 +202,17 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         param.put("tenantId", TenantContextHolder.getTenantId());
         //查询该人员分部  及 分部下包含的学校(合作单位)
         SysUser sysUser = getSysUser();
+        //分部
+        String organIds = null;
         //如果是超管就查询当前机构所有的直播间
         if (sysUser.getTenantId() == -1 || sysUser.getIsSuperAdmin()) {
             param.put("allRoom", 1);
         } else {
             Employee employee = employeeService.get(sysUser.getId());
             if (Objects.nonNull(employee) && Objects.nonNull(employee.getOrganIdList())) {
-                param.put("organIds", employee.getOrganIdList());
-                String schoolIds = baseMapper.querySchoolIds(employee.getOrganIdList());
+                organIds = employee.getOrganIdList();
+                param.put("organIds", organIds);
+                String schoolIds = baseMapper.querySchoolIds(organIds);
                 if (StringUtils.isNotBlank(schoolIds)) {
                     param.put("schoolIds", schoolIds);
                 }
@@ -435,9 +442,27 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
             return;
         }
         //获取直播间主讲人信息
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, room.getSpeakerId().toString()));
+        RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(room.getRoomUid(), room.getSpeakerId().toString());
         if (speakerCache.isExists()) {
             RoomSpeakerInfo speakerInfo = speakerCache.get();
+            //查询用户是否在线
+            if (imFeignService.checkOnline(speakerInfo.getSpeakerId().toString())) {
+                log.info("roomDestroy destroyExpiredLiveRoom  is online >>>> roomId:{} speakerId:{}", room.getId(), speakerInfo.getSpeakerId());
+                return;
+            }
+            //校验房间心跳是否过期没续租
+            RBucket<Date> lastRoomHeartbeatCache = redissonClient.getBucket(LIVE_ROOM_SPEAKER_HEART_BEAT.replace(ROOM_UID, room.getRoomUid()));
+            if (lastRoomHeartbeatCache.isExists()) {
+                //获取最后一次房间心跳时间
+                Date lastDate = lastRoomHeartbeatCache.get();
+                //房间心跳过期时间 = 将房间心跳时间+过期分钟
+                Date lastRoomDateExpired = DateUtil.addMinutes(lastDate, expiredMinute);
+                //当前时间 小于 房间心跳过期时间 则不销毁
+                if (now.getTime() <= lastRoomDateExpired.getTime()) {
+                    log.info("roomDestroy destroyExpiredLiveRoom  last room heartbeat  >>>> roomId:{} speakerId:{}", room.getId(), speakerInfo.getSpeakerId());
+                    return;
+                }
+            }
             //1.主播没有进入房间,则直接销毁房间
             if (Objects.isNull(speakerInfo.getJoinRoomTime())) {
                 log.info("roomDestroy not joinRoom >>>> cache : {}", JSONObject.toJSONString(test(room.getRoomUid())));
@@ -525,7 +550,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
             imFeignService.publishRoomMsg(message);
             log.info("roomDestroy>>>> FORCED_OFFLINE {}", JSONObject.toJSONString(message));
             //销毁直播间
-            imFeignService.destroyLiveRoom(roomUid);
+//            imFeignService.destroyLiveRoom(roomUid);
             log.info("roomDestroy>>>> destroyLiveRoom {}", JSONObject.toJSONString(message));
         } catch (Exception e) {
             log.error("roomDestroy>>>> errorMsg{}", e.getMessage(), e.getCause());
@@ -565,7 +590,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         }
         int speakerLiveTime = 0;
         //获取直播间主讲人信息 写入im_live_broadcast_room_data
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, speakerId.toString()));
+        RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(roomUid, speakerId.toString());
         if (speakerCache.isExists()) {
             ImLiveBroadcastRoomData liveData = new ImLiveBroadcastRoomData();
             RoomSpeakerInfo speakerInfo = speakerCache.get();
@@ -613,6 +638,8 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
     @Override
     public void syncLike(String roomUid, Integer likeNum) {
         redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid)).set(likeNum);
+        //增加房间心跳
+        redissonClient.getBucket(LIVE_ROOM_SPEAKER_HEART_BEAT.replace(ROOM_UID, roomUid)).set(new Date());
     }
 
     /**
@@ -645,20 +672,20 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
             }
             //将最新的时间写入缓存
             userStateTimeCache.set(userStateTime, 5L, TimeUnit.MINUTES);
+            //获取当前用户所在房间的uid
+            RBucket<String> userRoom = redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userid));
+            if (!userRoom.isExists()) {
+                return;
+            }
+            String roomUid = userRoom.get();
             //查询userId是不是主讲人 ,如果是主讲人则返回
-            if (isSpeaker(user, now, userid)) {
+            if (isSpeaker(user, now, userid, roomUid)) {
                 return;
             }
             //这里开始只处理观看者的数据,观看者只接受退出消息 status=0 是进入房间
             if (user.getStatus().equals("0")) {
                 return;
             }
-            //获取当前用户所在房间的uid
-            RBucket<String> userRoom = redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userid));
-            if (!userRoom.isExists()) {
-                return;
-            }
-            String roomUid = userRoom.get();
             Integer userId = Integer.valueOf(userid);
 
             //从房间累计用户信息中查询该用户的信息
@@ -738,19 +765,34 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      *
      * @return true 是主讲人 false 不是主讲人
      */
-    private boolean isSpeaker(ImUserState user, Date now, String userid) {
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userid));
+    private boolean isSpeaker(ImUserState user, Date now, String userid, String roomUid) {
+        RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(roomUid, userid);
         if (!speakerCache.isExists()) {
             return false;
         }
         RoomSpeakerInfo speakerInfo = speakerCache.get();
+        //最后一次进入房间的clientIp
+        RBucket<String> lastClientIp = redissonClient.getBucket(LIVE_SPEAKER_LAST_CLIENT_IP.replace(ROOM_UID, roomUid).replace(USER_ID, userid));
         //主讲人进入房间
         if (user.getStatus().equals("0")) {
             speakerInfo.setJoinRoomTime(now);
             log.info("opsRoom>>>> join speakerCache {}", JSONObject.toJSONString(speakerInfo));
             speakerCache.set(speakerInfo);
+            //将本次进入房间的clientIp添加到主讲人最后一次clientIp缓存中
+            if (StringUtils.isNotBlank(user.getClientIp())) {
+                lastClientIp.set(user.getClientIp());
+            }
             return true;
         }
+        //校验本次退出直播间的clientIp 是不是上次进入房间的clientIp
+        if (StringUtils.isNotBlank(user.getClientIp())) {
+            if (lastClientIp.isExists()) {
+                //如果是上次进入房间的clientIp和本次退出房间的clientIp不相同,则直接忽略
+                if (!user.getClientIp().equals(lastClientIp.get())) {
+                    return true;
+                }
+            }
+        }
         //主讲人退出房间关闭录像
         closeLive(speakerInfo);
         speakerInfo.setExitRoomTime(now);
@@ -773,15 +815,17 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         }
         Date now = new Date();
         //获取直播间信息
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+        RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(roomUid, userId.toString());
         if (!speakerCache.isExists()) {
             //没有主讲人信息则生成一个
             createSpeakerInfo(this.getById(roomVo.getId()), sysUser);
-            speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+            speakerCache = getRoomSpeakerInfoCache(roomUid, userId.toString());
         }
         RoomSpeakerInfo speakerInfo = speakerCache.get();
         speakerInfo.setJoinRoomTime(now);
         speakerCache.set(speakerInfo);
+        //记录用户当前房间uid
+        redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userId.toString())).set(roomUid, 12L, TimeUnit.HOURS);
         return roomVo;
     }
 
@@ -815,7 +859,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
             userInfo.setTotalViewTime(0);
         }
         //查询主讲人信息
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, imLiveBroadcastRoomVo.getSpeakerId().toString()));
+        RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(roomUid, imLiveBroadcastRoomVo.getSpeakerId().toString());
         if (speakerCache.isExists()) {
             //如果用户进来时主讲人已经开启直播则修改学生观看时间
             Integer state = speakerCache.get().getState();
@@ -841,7 +885,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      */
     public void startLive(String roomUid, Integer userId) {
         //查询房间信息
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+        RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(roomUid, userId.toString());
         if (!speakerCache.isExists()) {
             return;
         }
@@ -877,7 +921,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      */
     public void closeLive(String roomUid, Integer userId) {
         //查询房间主播信息
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
+        RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(roomUid, userId.toString());
         if (!speakerCache.isExists()) {
             return;
         }
@@ -948,7 +992,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
                 if (onlineUserInfoExists && onlineUserInfo.containsKey(id)) {
                     if (type.equals(1)) {
                         //开启直播后对当前在房间的用户写入观看时间
-                        userInfo.setDynamicLookTime(new Date());
+                        userInfo.setDynamicLookTime(now);
                     } else if (type.equals(2)) {
                         userInfo.setTotalViewTime(getLookMinutes(userInfo.getDynamicLookTime(), now, userInfo.getTotalViewTime()));
                         userInfo.setDynamicLookTime(null);
@@ -1036,7 +1080,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
             speakerInfo.setWhetherVideo(1);
         }
         //写入主讲人信息
-        redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, room.getSpeakerId().toString())).set(speakerInfo);
+        getRoomSpeakerInfoCache(room.getRoomUid(), room.getSpeakerId().toString()).set(speakerInfo);
 
         //生成0点赞
         redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, room.getRoomUid())).set(0);
@@ -1097,6 +1141,26 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
     public Map<String, Object> test(String roomUid) {
         //test
         Map<String, Object> result = new HashMap<>();
+        //校验房间心跳是否过期没续租
+        RBucket<Date> lastRoomHeartbeatCache = redissonClient.getBucket(LIVE_ROOM_SPEAKER_HEART_BEAT.replace(ROOM_UID, roomUid));
+        if (lastRoomHeartbeatCache.isExists()) {
+            result.put("房间心跳", DateUtil.dateToString(lastRoomHeartbeatCache.get(), DateUtil.EXPANDED_DATE_TIME_FORMAT));
+        } else {
+            result.put("房间心跳", "房间心跳不存在");
+        }
+        String userId = "";
+        try {
+            String[] split = roomUid.split("-");
+            userId = split[1];
+        } catch (Exception ignored) {
+        }
+        //获取主讲人信息
+        RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(roomUid, userId);
+        if (speakerCache.isExists()) {
+            result.put("主讲人信息", speakerCache.get());
+        } else {
+            result.put("主讲人信息", "主讲人信息不存在");
+        }
         //点赞数
         Object like = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid)).get();
         if (Objects.isNull(like)) {
@@ -1113,29 +1177,15 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         if (CollectionUtils.isNotEmpty(totalUserInfo)) {
             if (CollectionUtils.isNotEmpty(inRoomUserInfo)) {
                 look = inRoomUserInfo.size();
-                result.put("正在观看的人员信息", inRoomUserInfo);
+//                result.put("正在观看的人员信息", inRoomUserInfo);
             } else {
                 result.put("正在观看的人员信息", "没有正在观看的人员数据");
             }
             totalLook = totalUserInfo.size();
-            result.put("总人员数据", totalUserInfo);
+//            result.put("总人员数据", totalUserInfo);
         } else {
             result.put("总人员数据", "没有人员数据");
         }
-        String userId = "";
-        try {
-            String[] split = roomUid.split("-");
-            userId = split[1];
-        } catch (Exception ignored) {
-        }
-
-        //获取主讲人信息
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId));
-        if (speakerCache.isExists()) {
-            result.put("主讲人信息", speakerCache.get());
-        } else {
-            result.put("主讲人信息", "主讲人信息不存在");
-        }
         result.put("总观看人数", totalLook);
         result.put("实时观看数", look);
         return result;
@@ -1254,6 +1304,16 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         return redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
     }
 
+    /**
+     * 获取房间主讲人消息
+     *
+     * @param roomUid 房间uid
+     * @param userId  用户id
+     */
+    private RBucket<RoomSpeakerInfo> getRoomSpeakerInfoCache(String roomUid, String userId) {
+        return redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId).replace(ROOM_UID, roomUid));
+    }
+
     private RoomUserInfoVo getUserInfo(Integer userId) {
         RoomUserInfoVo userInfo = new RoomUserInfoVo();
         userInfo.setUserId(userId);

+ 10 - 0
mec-client-api/src/main/java/com/ym/mec/im/ImFeignService.java

@@ -188,4 +188,14 @@ public interface ImFeignService {
     @PostMapping(value = "/liveRoom/userExistInRoom")
     boolean userExistInRoom(@RequestParam("chatroomId") String chatroomId, @RequestParam("userId") String userId);
 
+    /**
+     * 查询用户是否在线
+     * 注意:断网时,用户状态返回可能不准确
+     *
+     * @param userId 要查询的用户 ID(必传)
+     * @return 在线状态,true 在线,false 不在线
+     */
+    @PostMapping(value = "/liveRoom/checkOnline")
+    boolean checkOnline(@RequestParam("userId") String userId);
+
 }

+ 6 - 0
mec-client-api/src/main/java/com/ym/mec/im/fallback/ImFeignServiceFallback.java

@@ -24,6 +24,7 @@ public class ImFeignServiceFallback implements ImFeignService {
     public Object groupCreate(GroupModel groupModel) {
         return null;
     }
+
     @Override
     public Object groupUpdate(GroupModel groupModel) {
         return null;
@@ -109,4 +110,9 @@ public class ImFeignServiceFallback implements ImFeignService {
         return false;
     }
 
+    @Override
+    public boolean checkOnline(String userId) {
+        return false;
+    }
+
 }

+ 1 - 1
mec-im/src/main/java/com/ym/config/ResourceServerConfig.java

@@ -15,7 +15,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
                         "/room/statusImMsg", "/group/batchDismiss", "/private/send", "/group/send",
                         "/group/dismiss", "/room/statusImMsg", "/history/get", "/user/statusImUser", "/liveRoom/recordSync",
                         "/liveRoom/publishRoomMsg", "/liveRoom/destroy", "/liveRoom/create", "/liveRoom/startRecord",
-                        "/liveRoom/stopRecord", "/liveRoom/userExistInRoom")
+                        "/liveRoom/stopRecord", "/liveRoom/userExistInRoom","/liveRoom/checkOnline")
                 .permitAll().anyRequest().authenticated().and().csrf().disable();
     }
 }

+ 5 - 0
mec-im/src/main/java/com/ym/controller/LiveRoomController.java

@@ -69,4 +69,9 @@ public class LiveRoomController {
         return liveRoomService.userExistInRoom(chatroomId, userId);
     }
 
+    @ApiOperation("查询用户是否在聊天室")
+    @PostMapping(value = "/checkOnline")
+    public boolean checkOnline(String userId) {
+        return liveRoomService.checkOnline(userId);
+    }
 }

+ 17 - 0
mec-im/src/main/java/com/ym/mec/im/IMHelper.java

@@ -6,6 +6,7 @@ import com.ym.mec.common.entity.BaseMessage;
 import com.ym.mec.common.exception.BizException;
 import com.ym.pojo.IMApiResultInfo;
 import com.ym.pojo.IMTokenInfo;
+import com.ym.pojo.IMUserOnlineInfo;
 import io.rong.util.GsonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -473,4 +474,20 @@ public class IMHelper {
         return (IMApiResultInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMApiResultInfo.class);
     }
 
+    /**
+     * 查询用户是否在线
+     * 注意:断网时,用户状态返回可能不准确
+     *
+     * @param userId 要查询的用户 ID(必传)
+     */
+    public IMUserOnlineInfo checkOnline(String userId) throws Exception {
+        String body = "&userId=" + URLEncoder.encode(userId, UTF8);
+        if (body.indexOf("&") == 0) {
+            body = body.substring(1);
+        }
+        HttpURLConnection conn = httpHelper.createIMPostHttpConnection("/user/checkOnline.json", "application/x-www-form-urlencoded");
+        httpHelper.setBodyParameter(body, conn);
+        return (IMUserOnlineInfo) GsonUtil.fromJson(httpHelper.returnResult(conn), IMUserOnlineInfo.class);
+    }
+
 }

+ 2 - 0
mec-im/src/main/java/com/ym/pojo/IMApiResultInfo.java

@@ -13,6 +13,8 @@ public class IMApiResultInfo {
     String errorMessage;
     //人员是否存在 true 存在  false 不存在
     Boolean isInChrm;
+    //在线状态,1为在线,0为不在线。
+    String status;
 
     public boolean isSuccess() {
         return code == 200;

+ 15 - 0
mec-im/src/main/java/com/ym/pojo/IMUserOnlineInfo.java

@@ -0,0 +1,15 @@
+package com.ym.pojo;
+
+import lombok.Data;
+
+@Data
+public class IMUserOnlineInfo {
+    // 返回码,200 为正常。
+    Integer code;
+    //在线状态,1为在线,0为不在线。
+    String status;
+
+    public boolean isSuccess() {
+        return code == 200;
+    }
+}

+ 30 - 9
mec-im/src/main/java/com/ym/service/Impl/LiveRoomServiceImpl.java

@@ -9,6 +9,7 @@ import com.ym.mec.common.entity.ImRoomMessage;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.im.IMHelper;
 import com.ym.pojo.IMApiResultInfo;
+import com.ym.pojo.IMUserOnlineInfo;
 import com.ym.pojo.RecordConfig;
 import com.ym.pojo.RecordNotify;
 import com.ym.service.LiveRoomService;
@@ -121,17 +122,14 @@ public class LiveRoomServiceImpl implements LiveRoomService {
             log.error("直播视频录制失败:resultInfo : {} ", returnResult);
         }
         String recordId = resultObject.getString("recordId");
-        ImLiveRoomVideo video = imLiveRoomVideoService.getOne(new QueryWrapper<ImLiveRoomVideo>()
-                .eq("room_uid_", roomId)
-                .eq("record_id_", recordId)
-                .eq("type", 0));
+        ImLiveRoomVideo video = imLiveRoomVideoService.getOne(new QueryWrapper<ImLiveRoomVideo>().eq("room_uid_", roomId).eq("record_id_", recordId).eq("type", 0));
         if (Objects.nonNull(video)) {
             return;
         }
-        imLiveRoomVideoService.save(initImLiveRoomVideo(roomId, recordId,new Date()));
+        imLiveRoomVideoService.save(initImLiveRoomVideo(roomId, recordId, new Date()));
     }
 
-    private ImLiveRoomVideo initImLiveRoomVideo(String roomId, String recordId,Date now) {
+    private ImLiveRoomVideo initImLiveRoomVideo(String roomId, String recordId, Date now) {
         ImLiveRoomVideo video = new ImLiveRoomVideo();
         video.setRoomUid(roomId);
         video.setRecordId(recordId);
@@ -163,8 +161,8 @@ public class LiveRoomServiceImpl implements LiveRoomService {
                 try {
                     Date now = new Date();
                     //获取最后一次录制视频
-                    ImLiveRoomVideo video = imLiveRoomVideoService.getDao().getLastRecord(roomId,recordNotify.getRecordId());
-                    if(Objects.isNull(video)){
+                    ImLiveRoomVideo video = imLiveRoomVideoService.getDao().getLastRecord(roomId, recordNotify.getRecordId());
+                    if (Objects.isNull(video)) {
                         log.error("获取录制视频失败:roomId : {} ,recordId:{}", roomId, recordNotify.getRecordId());
                         return;
                     }
@@ -177,7 +175,7 @@ public class LiveRoomServiceImpl implements LiveRoomService {
                         imLiveRoomVideo.setType(2);
                         imLiveRoomVideoService.save(imLiveRoomVideo);
                         return;
-                    }else {
+                    } else {
                         video.setEndTime(now);
                         video.setType(2);
                         video.setUrl(fileUrl);
@@ -216,6 +214,29 @@ public class LiveRoomServiceImpl implements LiveRoomService {
         return resultInfo.isSuccess() && resultInfo.getIsInChrm();
     }
 
+    /**
+     * 查询用户是否在线
+     * 注意:断网时,用户状态返回可能不准确
+     *
+     * @param userId 要查询的用户 ID(必传)
+     * @return true 在线,false 不在线
+     */
+    public boolean checkOnline(String userId) {
+        log.info("checkOnline userId : {}", userId);
+        IMUserOnlineInfo resultInfo;
+        try {
+            resultInfo = imHelper.checkOnline(userId);
+        } catch (Exception e) {
+            return false;
+        }
+        if (!resultInfo.isSuccess()) {
+            log.error("checkOnline userId : {}", userId);
+            return false;
+        }
+        log.info("checkOnline userId : {}  resultInfo code:{} status: {}", userId, resultInfo.getCode(), resultInfo.getStatus());
+        return Objects.equals("1", resultInfo.getStatus());
+    }
+
     public String getRoomSessionId(String roomId) {
         RBucket<String> bucket = redissonClient.getBucket("sessionId:" + roomId);
         if (bucket.isExists()) {

+ 2 - 0
mec-im/src/main/java/com/ym/service/LiveRoomService.java

@@ -45,4 +45,6 @@ public interface LiveRoomService {
 
     boolean userExistInRoom(String chatroomId, String userId);
 
+    boolean checkOnline(String userId);
+
 }