fix live mic token flow and idempotent go-up

This commit is contained in:
hy001 2026-04-16 16:22:51 +08:00
parent 8840045a91
commit d15ea98dc6
3 changed files with 111 additions and 91 deletions

View File

@ -281,33 +281,35 @@ public class ImRestController extends BaseController {
} }
/** /**
* 获取上麦token * 获取观众token
* *
* @param channelName * @param channelName
* @param userId * @param userId
* @return * @return
*/ */
public String createChannelSubscriberToken(String channelName, Long userId) { public String createChannelSubscriberToken(String channelName, Long userId) {
RtcTokenBuilder2 var3 = new RtcTokenBuilder2(); RtcTokenBuilder2 var3 = new RtcTokenBuilder2();
String token = var3.buildTokenWithUid(appId, certificate, channelName, Integer.parseInt(getAccount(userId)), RtcTokenBuilder2.Role.ROLE_SUBSCRIBER, 21600, 21600); String token = var3.buildTokenWithUid(appId, certificate, channelName, Integer.parseInt(getAccount(userId)), RtcTokenBuilder2.Role.ROLE_SUBSCRIBER, 21600, 21600);
userAgoraTokenCacheService.save(token, userId, Long.valueOf(channelName)); userAgoraTokenCacheService.removeRoom(userId, Long.valueOf(channelName));
return token; userAgoraTokenCacheService.saveRoom(token, userId, Long.valueOf(channelName));
} return token;
}
/**
* 获取房间token /**
* * 获取上麦token
* @param channelName *
* @param userId * @param channelName
* @return * @param userId
*/ * @return
public String createChannelPublisherToken(String channelName, Long userId) { */
RtcTokenBuilder2 var3 = new RtcTokenBuilder2(); public String createChannelPublisherToken(String channelName, Long userId) {
String token = var3.buildTokenWithUid(appId, certificate, channelName, Integer.parseInt(getAccount(userId)), RtcTokenBuilder2.Role.ROLE_PUBLISHER, 21600, 21600); RtcTokenBuilder2 var3 = new RtcTokenBuilder2();
userAgoraTokenCacheService.saveRoom(token, userId, Long.valueOf(channelName)); String token = var3.buildTokenWithUid(appId, certificate, channelName, Integer.parseInt(getAccount(userId)), RtcTokenBuilder2.Role.ROLE_PUBLISHER, 21600, 21600);
return token; userAgoraTokenCacheService.remove(userId, Long.valueOf(channelName));
} userAgoraTokenCacheService.save(token, userId, Long.valueOf(channelName));
return token;
}
/** /**
* 根据用户id获取用户account * 根据用户id获取用户account

View File

@ -1,10 +1,11 @@
package com.red.circle.live.app.command.mic; package com.red.circle.live.app.command.mic;
import com.red.circle.component.redis.service.RedisService; import com.red.circle.component.redis.service.RedisService;
import com.red.circle.external.inner.endpoint.message.TrtcClient; import com.red.circle.external.inner.endpoint.message.TrtcClient;
import com.red.circle.framework.core.asserts.ResponseAssert; import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.live.app.convertor.LiveMicAppConvertor; import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.live.app.dto.clientobject.LiveMicrophoneCO; import com.red.circle.live.app.convertor.LiveMicAppConvertor;
import com.red.circle.live.app.dto.clientobject.LiveMicrophoneCO;
import com.red.circle.live.app.dto.cmd.MicUpDownCmd; import com.red.circle.live.app.dto.cmd.MicUpDownCmd;
import com.red.circle.live.domain.gateway.LiveMicrophoneGateway; import com.red.circle.live.domain.gateway.LiveMicrophoneGateway;
import com.red.circle.live.domain.live.dto.LiveMicrophoneNoticeDTO; import com.red.circle.live.domain.live.dto.LiveMicrophoneNoticeDTO;
@ -53,27 +54,31 @@ public class LiveMicGoUpCmdExe {
public LiveMicrophoneCO execute(MicUpDownCmd cmd) { public LiveMicrophoneCO execute(MicUpDownCmd cmd) {
checkPermissions(cmd); checkPermissions(cmd);
LiveMicrophoneNoticeDTO noticeDTO = liveMicrophoneGateway.goUp( LiveMicrophoneNoticeDTO noticeDTO = liveMicrophoneGateway.goUp(
cmd.getRoomId(), cmd.getRoomId(),
cmd.getMickIndex(), cmd.getMickIndex(),
cmd.requiredReqUserId() cmd.requiredReqUserId()
); );
LiveMicrophoneCO notice = returnMicrophoneCO(cmd, noticeDTO); LiveMicrophoneCO notice = returnMicrophoneCO(cmd, noticeDTO);
String roomToken = userAgoraTokenCacheService.getUserAgoraToken(cmd.getReqUserId(), cmd.getRoomId()); notice.setRoomToken(refreshPublisherToken(cmd));
if (Objects.isNull(roomToken)) { //notice.setRoomToken(createAgoraTokenGoUp(cmd));
notice.setRoomToken(trtcClient.createAgoraTokenGoUp(cmd.getReqUserId(), cmd.getRoomId().toString()).getBody());
//notice.setRoomToken(trtcClient.createAgoraTokenGoUp(cmd.getReqUserId(),cmd.getRoomId().toString()).getBody());
userAgoraTokenCacheService.save(notice.getRoomToken(), cmd.getReqUserId(), cmd.getRoomId());
} else {
notice.setRoomToken(roomToken);
}
//notice.setRoomToken(createAgoraTokenGoUp(cmd));
// 房主邀请成员上麦 // 房主邀请成员上麦
handleRoomDailyTask(cmd); handleRoomDailyTask(cmd);
return notice; return notice;
} }
private String refreshPublisherToken(MicUpDownCmd cmd) {
String roomToken = trtcClient.createAgoraTokenGoUp(
cmd.getReqUserId(),
cmd.getRoomId().toString()
).getBody();
ResponseAssert.notNull(CommonErrorCode.THIRD_PARTY_SERVER_ERROR, roomToken);
userAgoraTokenCacheService.remove(cmd.getReqUserId(), cmd.getRoomId());
userAgoraTokenCacheService.save(roomToken, cmd.getReqUserId(), cmd.getRoomId());
return roomToken;
}
private void handleRoomDailyTask(MicUpDownCmd cmd) { private void handleRoomDailyTask(MicUpDownCmd cmd) {
try { try {

View File

@ -159,49 +159,62 @@ public class LiveMicrophoneGatewayImpl implements LiveMicrophoneGateway {
.collect(Collectors.toMap(LiveMicUser::getId, v -> v)); .collect(Collectors.toMap(LiveMicUser::getId, v -> v));
} }
@Override @Override
public LiveMicrophoneNoticeDTO goUp(Long roomId, Integer micIndex, Long userId) { public LiveMicrophoneNoticeDTO goUp(Long roomId, Integer micIndex, Long userId) {
micOpsLock(roomId, micIndex); micOpsLock(roomId, micIndex);
// RLock lock = redissonClient.getLock(roomId.toString()+micIndex.toString()+"room"); // RLock lock = redissonClient.getLock(roomId.toString()+micIndex.toString()+"room");
// lock.lock(); // lock.lock();
try { try {
// 验证用户是否真实存在 // 验证用户是否真实存在
ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, userProfileClient.getByUserId(userId)); ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, userProfileClient.getByUserId(userId));
RoomProfileDTO roomProfile = roomManagerClient.getById(roomId).getBody(); RoomProfileDTO roomProfile = roomManagerClient.getById(roomId).getBody();
// 房间是否真实存在 // 房间是否真实存在
ResponseAssert.notNull(RoomErrorCode.ROOM_NOT_EXISTS, roomProfile); ResponseAssert.notNull(RoomErrorCode.ROOM_NOT_EXISTS, roomProfile);
// 获取上麦克风需要数据
LiveMicrophone liveMicrophone = getLiveMicrophone(roomId, micIndex, userId); // 获取上麦克风需要数据
liveMicrophone.getUser().setCharmLevel(userLevelClient.getUserLevel(SysOriginPlatformEnum.valueOf(roomProfile.getSysOrigin()),userId).getBody().getCharmLevel()); LiveMicrophone liveMicrophone = getLiveMicrophone(roomId, micIndex, userId);
ResponseAssert.notNull(LiveMicErrorCode.MIC_INDEX_NOT_FOUND, liveMicrophone); ResponseAssert.notNull(LiveMicErrorCode.MIC_INDEX_NOT_FOUND, liveMicrophone);
ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, liveMicrophone.getUser()); ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, liveMicrophone.getUser());
checkMicAvailableUse(roomId, micIndex);
// 下掉已上麦克风 if (liveMicCacheService.checkEqSelf(roomId, micIndex, userId)) {
List<LiveMicrophone> lives = liveMicCacheService.listLiveMicrophone(roomId, userId); liveMicCacheService.refreshNotActiveUser(roomId);
if (CollectionUtils.isNotEmpty(lives)) { return micUserChangeNotice(roomProfile);
liveMicCacheService.goDown(roomId, }
lives.stream().map(LiveMicrophone::getMicIndex).toList());
} checkMicAvailableUse(roomId, micIndex);
liveMicrophone.getUser().setCharmLevel(
// 上麦克风 userLevelClient.getUserLevel(
liveMicCacheService.goUp(roomId, micIndex, liveMicrophone); SysOriginPlatformEnum.valueOf(roomProfile.getSysOrigin()),
userId
// 清理活跃用户 ).getBody().getCharmLevel()
liveMicCacheService.refreshNotActiveUser(roomId); );
// 发送通知 // 下掉已上麦克风
return micUserChangeNotice(roomProfile); List<LiveMicrophone> lives = liveMicCacheService.listLiveMicrophone(roomId, userId);
}catch (Exception e){ if (CollectionUtils.isNotEmpty(lives)) {
e.printStackTrace(); List<Integer> goDownMicIndex = lives.stream()
ResponseAssert.isTrue(LiveMicErrorCode.MICROPHONE_OCCUPIED,false); .map(LiveMicrophone::getMicIndex)
return null; .filter(index -> !Objects.equals(index, micIndex))
} .toList();
finally { if (CollectionUtils.isNotEmpty(goDownMicIndex)) {
// lock.unlock(); liveMicCacheService.goDown(roomId, goDownMicIndex);
micOpsUnlock(roomId, micIndex); }
} }
}
// 上麦克风
liveMicCacheService.goUp(roomId, micIndex, liveMicrophone);
// 清理活跃用户
liveMicCacheService.refreshNotActiveUser(roomId);
// 发送通知
return micUserChangeNotice(roomProfile);
} finally {
// lock.unlock();
micOpsUnlock(roomId, micIndex);
}
}
@Override @Override
public void goDown(Long roomId, Integer micIndex, Long userId) { public void goDown(Long roomId, Integer micIndex, Long userId) {