|
@@ -75,6 +75,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
@Autowired
|
|
|
private ImLiveBroadcastRoomDataService liveBroadcastRoomDataService;
|
|
|
|
|
|
+ //待替换的变量
|
|
|
public static final String USER_ID = "${userId}";
|
|
|
public static final String ROOM_UID = "${roomUid}";
|
|
|
|
|
@@ -375,25 +376,15 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
}
|
|
|
|
|
|
public void roomDestroy(ImLiveBroadcastRoom room) {
|
|
|
+ //10秒内同一个房间不能重复销毁-防重复销毁
|
|
|
+ RBucket<Object> bucket = redissonClient.getBucket("IM:ROOMDESTROY:" + room.getRoomUid());
|
|
|
+ if (!bucket.trySet(1, 10, TimeUnit.SECONDS)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
log.error("roomDestroy>>>> room : {}", JSONObject.toJSONString(room));
|
|
|
String roomUid = room.getRoomUid();
|
|
|
Integer speakerId = room.getSpeakerId();
|
|
|
|
|
|
- try {
|
|
|
- //向聊天室发自定义消息踢出所有人
|
|
|
- ImRoomMessage message = new ImRoomMessage();
|
|
|
- message.setFromUserId(speakerId.toString());
|
|
|
- message.setToChatroomId(roomUid);
|
|
|
- message.setObjectName(ImRoomMessage.FORCED_OFFLINE);
|
|
|
- imFeignService.publishRoomMsg(message);
|
|
|
- log.info("roomDestroy>>>> FORCED_OFFLINE {}", JSONObject.toJSONString(message));
|
|
|
- //销毁直播间
|
|
|
- imFeignService.destroyLiveRoom(roomUid);
|
|
|
- log.info("roomDestroy>>>> destroyLiveRoom {}", JSONObject.toJSONString(message));
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("roomDestroy>>>> errorMsg{}", e.getMessage(), e.getCause());
|
|
|
- }
|
|
|
-
|
|
|
//获取所有直播间缓存数据并写入数据库后并清理缓存
|
|
|
insertAndCleanLiveData(roomUid, speakerId);
|
|
|
log.info("roomDestroy>>>> insertAndCleanLiveData {}", JSONObject.toJSONString(room));
|
|
@@ -412,6 +403,21 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
room.setLiveEndTime(date);
|
|
|
room.setPopularize(0);//销毁直播间后要关闭推广
|
|
|
this.updateById(room);
|
|
|
+
|
|
|
+ //向聊天室发自定义消息踢出所有人
|
|
|
+ try {
|
|
|
+ ImRoomMessage message = new ImRoomMessage();
|
|
|
+ message.setFromUserId(speakerId.toString());
|
|
|
+ message.setToChatroomId(roomUid);
|
|
|
+ message.setObjectName(ImRoomMessage.FORCED_OFFLINE);
|
|
|
+ imFeignService.publishRoomMsg(message);
|
|
|
+ log.info("roomDestroy>>>> FORCED_OFFLINE {}", JSONObject.toJSONString(message));
|
|
|
+ //销毁直播间
|
|
|
+ imFeignService.destroyLiveRoom(roomUid);
|
|
|
+ log.info("roomDestroy>>>> destroyLiveRoom {}", JSONObject.toJSONString(message));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("roomDestroy>>>> errorMsg{}", e.getMessage(), e.getCause());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//获取该直播间所有数据写入数据库-并清理缓存
|
|
@@ -428,16 +434,9 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
member.setRoomUid(roomUid);
|
|
|
member.setUserId(v.getUserId());
|
|
|
member.setJoinTime(v.getFirstJoinTime());
|
|
|
- member.setTotalTime(v.getTotalViewTime());
|
|
|
+ member.setTotalTime(getLookMinutes(v.getDynamicLookTime(), v.getTotalViewTime()));
|
|
|
memberList.add(member);
|
|
|
}
|
|
|
- //删除用户对应的直播间关系缓存
|
|
|
- roomTotalUser.stream()
|
|
|
- .map(RoomUserInfoVo::getUserId)
|
|
|
- .filter(Objects::nonNull)
|
|
|
- .forEach(id -> redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, id.toString())).delete());
|
|
|
- //删除直播间所有人数据
|
|
|
- roomTotalUserCache.clear();
|
|
|
}
|
|
|
|
|
|
//获取直播点赞
|
|
@@ -459,7 +458,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
liveData.setLikeNum(like);
|
|
|
liveData.setTotalUserNum(CollectionUtils.isNotEmpty(memberList) ? memberList.size() : 0);
|
|
|
liveData.setUpdatedTime(new Date());
|
|
|
- liveData.setLiveTime(speakerInfo.getTotalLiveTime());
|
|
|
+ liveData.setLiveTime(getLookMinutes(speakerInfo.getStartLiveTime(), speakerInfo.getTotalLiveTime()));
|
|
|
liveBroadcastRoomDataService.save(liveData);
|
|
|
//删除房间主讲人数据
|
|
|
speakerCache.delete();
|
|
@@ -475,7 +474,14 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
}
|
|
|
}
|
|
|
liveBroadcastRoomMemberService.getDao().insertBatch(memberList);
|
|
|
+ //删除用户对应的直播间关系缓存
|
|
|
+ memberList.stream()
|
|
|
+ .map(ImLiveBroadcastRoomMember::getUserId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .forEach(id -> redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, id.toString())).delete());
|
|
|
}
|
|
|
+ //删除直播间所有用户数据
|
|
|
+ roomTotalUserCache.clear();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -573,8 +579,8 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
}
|
|
|
//只有在主播开播后用户才有观看时间,才需要计算当前用户观看时长
|
|
|
if (Objects.nonNull(userInfo.getDynamicLookTime())) {
|
|
|
- int minutesBetween = getMinutesBetween(userInfo.getDynamicLookTime(), now);
|
|
|
- userInfo.setTotalViewTime(userInfo.getTotalViewTime() + minutesBetween);
|
|
|
+ userInfo.setTotalViewTime(getLookMinutes(userInfo.getDynamicLookTime(), userInfo.getTotalViewTime()));
|
|
|
+ userInfo.setDynamicLookTime(null);
|
|
|
}
|
|
|
//记录退出时间 并写入缓存
|
|
|
userInfo.setState(1);
|
|
@@ -701,6 +707,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
speakerCache.set(roomSpeakerInfo);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
private void closeLive(RoomSpeakerInfo roomSpeakerInfo) {
|
|
|
//直播状态 true 直播中 false关闭直播
|
|
|
boolean stateFlag = Objects.nonNull(roomSpeakerInfo.getState()) && roomSpeakerInfo.getState() == 0;
|
|
@@ -720,15 +727,10 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
Date now = new Date();
|
|
|
roomSpeakerInfo.setEndLiveTime(now);
|
|
|
roomSpeakerInfo.setState(1);
|
|
|
- //计算时长方法
|
|
|
- BiFunction<Date, Integer, Integer> getLookMinutes = (startDate, nowMinutes) -> {
|
|
|
- int minutesBetween = getMinutesBetween(startDate, new Date());
|
|
|
- minutesBetween += Objects.isNull(nowMinutes) ? 0 : nowMinutes;
|
|
|
- return Math.max(minutesBetween, 0);
|
|
|
- };
|
|
|
//写入本次直播时长
|
|
|
- int lookMinutes = getLookMinutes.apply(roomSpeakerInfo.getStartLiveTime(), roomSpeakerInfo.getTotalLiveTime());
|
|
|
- roomSpeakerInfo.setTotalLiveTime(lookMinutes);
|
|
|
+ roomSpeakerInfo.setTotalLiveTime(getLookMinutes(roomSpeakerInfo.getStartLiveTime(), roomSpeakerInfo.getTotalLiveTime()));
|
|
|
+ //计算完后将开始直播时间设置为空,待下次开启后再计算
|
|
|
+ roomSpeakerInfo.setStartLiveTime(null);
|
|
|
//主播关闭直播,查询所有在直播间的用户并计算观看时长
|
|
|
RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomSpeakerInfo.getRoomUid()));
|
|
|
if (!roomTotalUser.isExists()) {
|
|
@@ -737,8 +739,8 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
roomTotalUser.forEach((id, userInfo) -> {
|
|
|
//对在房间的用户计算观看时长
|
|
|
if (Objects.nonNull(userInfo.getState()) && userInfo.getState() == 0) {
|
|
|
- Integer userLookMinutes = getLookMinutes.apply(userInfo.getDynamicLookTime(), userInfo.getTotalViewTime());
|
|
|
- userInfo.setTotalViewTime(userLookMinutes);
|
|
|
+ userInfo.setTotalViewTime(getLookMinutes(userInfo.getDynamicLookTime(), userInfo.getTotalViewTime()));
|
|
|
+ userInfo.setDynamicLookTime(null);
|
|
|
roomTotalUser.fastPut(id, userInfo);
|
|
|
}
|
|
|
});
|
|
@@ -965,9 +967,25 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
return userInfo;
|
|
|
}
|
|
|
|
|
|
- //计算时间差-分钟数不满一分钟为0
|
|
|
- private int getMinutesBetween(Date startDT, Date endDT) {
|
|
|
- if (Objects.isNull(startDT) || Objects.isNull(endDT)) {
|
|
|
+ /**
|
|
|
+ * 计算观看时长差-分钟数不满一分钟为0
|
|
|
+ *
|
|
|
+ * @param startDT 开始时间
|
|
|
+ * @param nowMinutes 现在观看时长
|
|
|
+ */
|
|
|
+ private int getLookMinutes(Date startDT, Integer nowMinutes) {
|
|
|
+ return getLookMinutes(startDT, new Date(), nowMinutes);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算观看时长差-分钟数不满一分钟为0
|
|
|
+ *
|
|
|
+ * @param startDT 开始时间
|
|
|
+ * @param endDT 结束时间
|
|
|
+ * @param nowMinutes 现在观看时长
|
|
|
+ */
|
|
|
+ private int getLookMinutes(Date startDT, Date endDT, Integer nowMinutes) {
|
|
|
+ if (Objects.isNull(startDT)) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (startDT.getTime() > endDT.getTime()) {
|
|
@@ -976,7 +994,9 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
|
|
|
//课程结束时间-课程开始时间
|
|
|
long durationTime = endDT.getTime() - startDT.getTime();
|
|
|
//相差多少分钟
|
|
|
- return new Long(durationTime / 1000 / 60).intValue();
|
|
|
+ int minutesBetween = new Long(durationTime / 1000 / 60).intValue();
|
|
|
+ minutesBetween += Objects.isNull(nowMinutes) ? 0 : nowMinutes;
|
|
|
+ return Math.max(minutesBetween, 0);
|
|
|
}
|
|
|
|
|
|
/**
|