|  | @@ -146,7 +146,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |      //直播提前开始时间
 | 
	
		
			
				|  |  |      public static final int PRE_LIVE_TIME_MINUTE = 30;
 | 
	
		
			
				|  |  |      //主讲人信息
 | 
	
		
			
				|  |  | -    public static final String SPEAKER_ROOM_ING_INFO = String.join(":", "IM:SPEAKER_ROOM_ING_INFO", USER_ID);
 | 
	
		
			
				|  |  | +    public static final String SPEAKER_ROOM_ING_INFO_LOCK = String.join(":", "IM:SPEAKER_ROOM_ING_INFO_LOCK", USER_ID);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 进入直播间检查数据
 | 
	
	
		
			
				|  | @@ -718,9 +718,6 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |                      pluginService.rtcRoomRecordStop(taskId);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            redissonClient.getBucket(
 | 
	
		
			
				|  |  | -                SPEAKER_ROOM_ING_INFO.replace(USER_ID, room.getSpeakerId().toString())).delete();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  //            imFeignService.destroyLiveRoom(roomUid);
 | 
	
		
			
				|  |  |              log.info("roomDestroy>>>> destroyLiveRoom {}", JSONObject.toJSONString(message));
 | 
	
		
			
				|  |  |          } catch (Exception e) {
 | 
	
	
		
			
				|  | @@ -1688,14 +1685,23 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |          Collection<ImLiveBroadcastRoom> values = list.stream()
 | 
	
		
			
				|  |  |                                                       .collect(Collectors.toMap(o -> o.getSpeakerId(), o -> o, (k1, k2) -> k1))
 | 
	
		
			
				|  |  |                                                       .values();
 | 
	
		
			
				|  |  | -        values.forEach(this::createLiveRoom);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for (ImLiveBroadcastRoom value : values) {
 | 
	
		
			
				|  |  | +            try {
 | 
	
		
			
				|  |  | +                createLiveRoom(value);
 | 
	
		
			
				|  |  | +            } catch (Exception e) {
 | 
	
		
			
				|  |  | +                log.error("createLiveRoom error:{}", e.getMessage());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          createLock.delete();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 去融云创建房间
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    private void createLiveRoom(ImLiveBroadcastRoom room) {
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | +    public void createLiveRoom(ImLiveBroadcastRoom room) {
 | 
	
		
			
				|  |  |          log.info("createLiveRoom>>>>>>roomUid:{}", room.getRoomUid());
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              //生成主讲人信息到缓存
 | 
	
	
		
			
				|  | @@ -1703,70 +1709,94 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //记录用户当前房间uid
 | 
	
		
			
				|  |  | -            RBucket<String> bucket = redissonClient.getBucket(
 | 
	
		
			
				|  |  | -                SPEAKER_ROOM_ING_INFO.replace(USER_ID, room.getSpeakerId().toString()));
 | 
	
		
			
				|  |  | +            RLock lock = redissonClient.getLock(SPEAKER_ROOM_ING_INFO_LOCK.replace(USER_ID, room.getSpeakerId().toString()));
 | 
	
		
			
				|  |  | +            boolean b = lock.tryLock(10L, TimeUnit.SECONDS);
 | 
	
		
			
				|  |  | +            if (!b) {
 | 
	
		
			
				|  |  | +                log.info("createLiveRoom>>>>>>lock is exists");
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            try {
 | 
	
		
			
				|  |  | +                // 判断是否有正在直播的房间
 | 
	
		
			
				|  |  | +                List<ImLiveBroadcastRoom> list = this.lambdaQuery()
 | 
	
		
			
				|  |  | +                                                     .eq(ImLiveBroadcastRoom::getSpeakerId, room.getSpeakerId())
 | 
	
		
			
				|  |  | +                                                     .eq(ImLiveBroadcastRoom::getLiveState, 1)
 | 
	
		
			
				|  |  | +                                                     .eq(ImLiveBroadcastRoom::getRoomState, 0)
 | 
	
		
			
				|  |  | +                                                     .list();
 | 
	
		
			
				|  |  | +                if (CollectionUtils.isNotEmpty(list)) {
 | 
	
		
			
				|  |  | +                    throw new BizException("当前用户已经有正在直播的房间");
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                ImLiveBroadcastRoom one = this.lambdaQuery()
 | 
	
		
			
				|  |  | +                                              .eq(ImLiveBroadcastRoom::getSpeakerId, room.getSpeakerId())
 | 
	
		
			
				|  |  | +                                              .eq(ImLiveBroadcastRoom::getLiveState, 0)
 | 
	
		
			
				|  |  | +                                              .eq(ImLiveBroadcastRoom::getRoomState, 0)
 | 
	
		
			
				|  |  | +                                              .orderByAsc(ImLiveBroadcastRoom::getLiveStartTime)
 | 
	
		
			
				|  |  | +                                              .last("limit 1")
 | 
	
		
			
				|  |  | +                                              .one();
 | 
	
		
			
				|  |  | +                if (one == null) {
 | 
	
		
			
				|  |  | +                    throw new BizException("当前用户没有待直播的房间");
 | 
	
		
			
				|  |  | +                } else if (!one.getRoomUid().equals(room.getRoomUid())) {
 | 
	
		
			
				|  |  | +                    throw new BizException("当前用户存在更早的待直播的房间");
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            if (bucket.isExists()) {
 | 
	
		
			
				|  |  | -                ImLiveBroadcastRoomVo imLiveBroadcastRoomVo = getImLiveBroadcastRoomVo(bucket.get());
 | 
	
		
			
				|  |  | -                if (imLiveBroadcastRoomVo != null && imLiveBroadcastRoomVo.getLiveState() == 1) {
 | 
	
		
			
				|  |  | -                    log.info("createLiveRoom>>>>>>roomUid:{} is exists", bucket.get());
 | 
	
		
			
				|  |  | -                    return;
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            //去融云创建房间
 | 
	
		
			
				|  |  | -            LivePluginService pluginService = livePluginContext.getPluginService(room.getServiceProvider());
 | 
	
		
			
				|  |  | +                //去融云创建房间
 | 
	
		
			
				|  |  | +                LivePluginService pluginService = livePluginContext.getPluginService(room.getServiceProvider());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // 注册主播用户信息到三方平台
 | 
	
		
			
				|  |  | -            pluginService.register(sysUser.getId().toString(), sysUser.getUsername(), sysUser.getAvatar());
 | 
	
		
			
				|  |  | -            // 创建直播间IM群
 | 
	
		
			
				|  |  | -            pluginService.chatRoomCreate(room.getRoomUid(), room.getRoomTitle(),sysUser.getId().toString());
 | 
	
		
			
				|  |  | +                // 注册主播用户信息到三方平台
 | 
	
		
			
				|  |  | +                pluginService.register(sysUser.getId().toString(), sysUser.getUsername(), sysUser.getAvatar());
 | 
	
		
			
				|  |  | +                // 创建直播间IM群
 | 
	
		
			
				|  |  | +                pluginService.chatRoomCreate(room.getRoomUid(), room.getRoomTitle(),sysUser.getId().toString());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            createSpeakerInfo(room, sysUser);
 | 
	
		
			
				|  |  | -            Boolean whetherVideoFlag = getRoomConfig(room.getRoomConfig()).map(o -> o.getWhether_video() == 0).orElse(true);
 | 
	
		
			
				|  |  | +                createSpeakerInfo(room, sysUser);
 | 
	
		
			
				|  |  | +                Boolean whetherVideoFlag = getRoomConfig(room.getRoomConfig()).map(o -> o.getWhether_video() == 0).orElse(true);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // 腾讯云直播,提前生成录制规则
 | 
	
		
			
				|  |  | -            if (room.getServiceProvider().equals(TencentCloudLivePlugin.PLUGIN_NAME) && whetherVideoFlag) {
 | 
	
		
			
				|  |  | +                // 腾讯云直播,提前生成录制规则
 | 
	
		
			
				|  |  | +                if (room.getServiceProvider().equals(TencentCloudLivePlugin.PLUGIN_NAME) && whetherVideoFlag) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                DateTime now = DateTime.now();
 | 
	
		
			
				|  |  | +                    DateTime now = DateTime.now();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                RTCRequest.RecordStart recordStart = RTCRequest.RecordStart.builder()
 | 
	
		
			
				|  |  | -                        .streamName(MessageFormat.format("{0}_{1}", room.getRoomUid(), room.getSpeakerId().toString()))
 | 
	
		
			
				|  |  | -                        .extra("")
 | 
	
		
			
				|  |  | -                        .startTime(now.toDateTime().getMillis())
 | 
	
		
			
				|  |  | -                        .endTime(now.plusDays(1).toDateTime().getMillis())
 | 
	
		
			
				|  |  | -                        .build();
 | 
	
		
			
				|  |  | +                    RTCRequest.RecordStart recordStart = RTCRequest.RecordStart.builder()
 | 
	
		
			
				|  |  | +                                                   .streamName(MessageFormat.format("{0}_{1}", room.getRoomUid(), room.getSpeakerId().toString()))
 | 
	
		
			
				|  |  | +                                                   .extra("")
 | 
	
		
			
				|  |  | +                                                   .startTime(now.toDateTime().getMillis())
 | 
	
		
			
				|  |  | +                                                   .endTime(now.plusDays(1).toDateTime().getMillis())
 | 
	
		
			
				|  |  | +                                                   .build();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                // 生成录制任务
 | 
	
		
			
				|  |  | -                pluginService.rtcRoomRecordStart(recordStart);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +                    // 生成录制任务
 | 
	
		
			
				|  |  | +                    pluginService.rtcRoomRecordStart(recordStart);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // imFeignService.createLiveRoom(room.getRoomUid(), room.getRoomTitle());
 | 
	
		
			
				|  |  | -            //推送预约直播间消息
 | 
	
		
			
				|  |  | -            imLiveRoomReservationService.push(room);
 | 
	
		
			
				|  |  | +                // imFeignService.createLiveRoom(room.getRoomUid(), room.getRoomTitle());
 | 
	
		
			
				|  |  | +                //推送预约直播间消息
 | 
	
		
			
				|  |  | +                imLiveRoomReservationService.push(room);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            //推送直播开始消息
 | 
	
		
			
				|  |  | -            this.sendRoomLiveState(sysUser, room, MessageTypeEnum.JIGUANG_LIVE_STARTED);
 | 
	
		
			
				|  |  | +                //推送直播开始消息
 | 
	
		
			
				|  |  | +                this.sendRoomLiveState(sysUser, room, MessageTypeEnum.JIGUANG_LIVE_STARTED);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // 查询黑名单人员
 | 
	
		
			
				|  |  | -            List<ImLiveRoomBlack> blackList = imLiveRoomBlackService.lambdaQuery()
 | 
	
		
			
				|  |  | -                .eq(ImLiveRoomBlack::getRoomUid, room.getRoomUid())
 | 
	
		
			
				|  |  | -                .list();
 | 
	
		
			
				|  |  | +                // 查询黑名单人员
 | 
	
		
			
				|  |  | +                List<ImLiveRoomBlack> blackList = imLiveRoomBlackService.lambdaQuery()
 | 
	
		
			
				|  |  | +                                                                        .eq(ImLiveRoomBlack::getRoomUid, room.getRoomUid())
 | 
	
		
			
				|  |  | +                                                                        .list();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            ImLiveBroadcastRoomVo roomVo = getImLiveBroadcastRoomVo(room.getRoomUid());
 | 
	
		
			
				|  |  | -            if (CollectionUtils.isNotEmpty(blackList)) {
 | 
	
		
			
				|  |  | -                // 将黑名单人员踢出房间
 | 
	
		
			
				|  |  | -                for (ImLiveRoomBlack black : blackList) {
 | 
	
		
			
				|  |  | -                    imLiveRoomBlackService.setBlack(black.getUserId(),roomVo);
 | 
	
		
			
				|  |  | +                ImLiveBroadcastRoomVo roomVo = getImLiveBroadcastRoomVo(room.getRoomUid());
 | 
	
		
			
				|  |  | +                if (CollectionUtils.isNotEmpty(blackList)) {
 | 
	
		
			
				|  |  | +                    // 将黑名单人员踢出房间
 | 
	
		
			
				|  |  | +                    for (ImLiveRoomBlack black : blackList) {
 | 
	
		
			
				|  |  | +                        imLiveRoomBlackService.setBlack(black.getUserId(),roomVo);
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                // 设置直播间房间属性默认值
 | 
	
		
			
				|  |  | +                setDefaultRoomDefinedInfo(roomVo);
 | 
	
		
			
				|  |  | +            } finally {
 | 
	
		
			
				|  |  | +                if (lock.getHoldCount() != 0 && lock.isHeldByCurrentThread()) {
 | 
	
		
			
				|  |  | +                    lock.unlock();
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // 设置直播间房间属性默认值
 | 
	
		
			
				|  |  | -            setDefaultRoomDefinedInfo(roomVo);
 | 
	
		
			
				|  |  | -            bucket.set(room.getRoomUid());
 | 
	
		
			
				|  |  |          } catch (Exception e) {
 | 
	
		
			
				|  |  |              log.error(">>>>>>>>>> createLiveRoom error roomUid:{} msg:{}", room.getRoomUid(), e.getMessage());
 | 
	
		
			
				|  |  | +            throw new BizException(e.getMessage());
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 |