修复点播异常后无法再次点播的BUG

pull/1669/head
648540858 2024-10-29 18:20:24 +08:00
parent 0bbac37135
commit daa8e8358c
3 changed files with 37 additions and 12 deletions

View File

@ -33,6 +33,8 @@ public class InviteInfo {
private Long expirationTime; private Long expirationTime;
private Long createTime;
public static InviteInfo getInviteInfo(String deviceId, Integer channelId, String stream, SSRCInfo ssrcInfo, String mediaServerId, public static InviteInfo getInviteInfo(String deviceId, Integer channelId, String stream, SSRCInfo ssrcInfo, String mediaServerId,
String receiveIp, Integer receivePort, String streamMode, String receiveIp, Integer receivePort, String streamMode,

View File

@ -18,7 +18,7 @@ public class VideoManagerConstants {
public static final String DEVICE_PREFIX = "VMP_DEVICE_INFO"; public static final String DEVICE_PREFIX = "VMP_DEVICE_INFO";
public static final String INVITE_PREFIX = "VMP_INVITE_INFO"; public static final String INVITE_PREFIX = "VMP_GB_INVITE_INFO";
public static final String PLATFORM_CATCH_PREFIX = "VMP_PLATFORM_CATCH_"; public static final String PLATFORM_CATCH_PREFIX = "VMP_PLATFORM_CATCH_";

View File

@ -17,6 +17,7 @@ import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ScanOptions;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
@ -115,11 +116,13 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
inviteInfoForUpdate = inviteInfoInRedis; inviteInfoForUpdate = inviteInfoInRedis;
} }
if (inviteInfoForUpdate.getCreateTime() == null) {
inviteInfoForUpdate.setCreateTime(System.currentTimeMillis());
}
String key = VideoManagerConstants.INVITE_PREFIX; String key = VideoManagerConstants.INVITE_PREFIX;
String objectKey = inviteInfoForUpdate.getType() + String objectKey = inviteInfoForUpdate.getType() +
":" + inviteInfoForUpdate.getChannelId() + ":" + inviteInfoForUpdate.getChannelId() +
":" + inviteInfoForUpdate.getStream() + ":" + inviteInfoForUpdate.getStream();
":" + inviteInfoForUpdate.getSsrcInfo().getSsrc();
if (time != null && time > 0) { if (time != null && time > 0) {
inviteInfoForUpdate.setExpirationTime(time); inviteInfoForUpdate.setExpirationTime(time);
} }
@ -137,8 +140,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
String key = VideoManagerConstants.INVITE_PREFIX; String key = VideoManagerConstants.INVITE_PREFIX;
String objectKey = inviteInfo.getType() + String objectKey = inviteInfo.getType() +
":" + inviteInfo.getChannelId() + ":" + inviteInfo.getChannelId() +
":" + stream + ":" + stream;
":" + inviteInfo.getSsrcInfo().getSsrc();
inviteInfoInDb.setStream(stream); inviteInfoInDb.setStream(stream);
if (inviteInfoInDb.getSsrcInfo() != null) { if (inviteInfoInDb.getSsrcInfo() != null) {
inviteInfoInDb.getSsrcInfo().setStream(stream); inviteInfoInDb.getSsrcInfo().setStream(stream);
@ -146,6 +148,9 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
if (InviteSessionStatus.ready == inviteInfo.getStatus()) { if (InviteSessionStatus.ready == inviteInfo.getStatus()) {
inviteInfoInDb.setExpirationTime((long) (userSetting.getPlayTimeout() * 2)); inviteInfoInDb.setExpirationTime((long) (userSetting.getPlayTimeout() * 2));
} }
if (inviteInfoInDb.getCreateTime() == null) {
inviteInfoInDb.setCreateTime(System.currentTimeMillis());
}
redisTemplate.opsForHash().put(key, objectKey, inviteInfoInDb); redisTemplate.opsForHash().put(key, objectKey, inviteInfoInDb);
return inviteInfoInDb; return inviteInfoInDb;
} }
@ -155,8 +160,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
String key = VideoManagerConstants.INVITE_PREFIX; String key = VideoManagerConstants.INVITE_PREFIX;
String keyPattern = (type != null ? type : "*") + String keyPattern = (type != null ? type : "*") +
":" + (channelId != null ? channelId : "*") + ":" + (channelId != null ? channelId : "*") +
":" + (stream != null ? stream : "*") ":" + (stream != null ? stream : "*");
+ ":*";
ScanOptions options = ScanOptions.scanOptions().match(keyPattern).count(20).build(); ScanOptions options = ScanOptions.scanOptions().match(keyPattern).count(20).build();
try (Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(key, options)) { try (Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(key, options)) {
if (cursor.hasNext()) { if (cursor.hasNext()) {
@ -206,8 +210,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
if (inviteInfo != null) { if (inviteInfo != null) {
String objectKey = inviteInfo.getType() + String objectKey = inviteInfo.getType() +
":" + inviteInfo.getChannelId() + ":" + inviteInfo.getChannelId() +
":" + stream + ":" + inviteInfo.getStream();
":" + inviteInfo.getSsrcInfo().getSsrc();
redisTemplate.opsForHash().delete(key, objectKey); redisTemplate.opsForHash().delete(key, objectKey);
} }
} }
@ -291,7 +294,6 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
private String buildSubStreamKey(InviteSessionType type, Integer channelId, String stream) { private String buildSubStreamKey(InviteSessionType type, Integer channelId, String stream) {
String key = type + ":" + channelId; String key = type + ":" + channelId;
// 如果ssrc为null那么可以实现一个通道只能一次操作ssrc不为null则可以支持一个通道多次invite
if (stream != null) { if (stream != null) {
key += (":" + stream); key += (":" + stream);
} }
@ -322,12 +324,33 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
String key = VideoManagerConstants.INVITE_PREFIX; String key = VideoManagerConstants.INVITE_PREFIX;
String objectKey = inviteInfo.getType() + String objectKey = inviteInfo.getType() +
":" + inviteInfo.getChannelId() + ":" + inviteInfo.getChannelId() +
":" + inviteInfo.getStream() + ":" + inviteInfo.getStream();
":" + ssrc;
if (inviteInfoInDb.getSsrcInfo() != null) { if (inviteInfoInDb.getSsrcInfo() != null) {
inviteInfoInDb.getSsrcInfo().setSsrc(ssrc); inviteInfoInDb.getSsrcInfo().setSsrc(ssrc);
} }
redisTemplate.opsForHash().put(key, objectKey, inviteInfoInDb); redisTemplate.opsForHash().put(key, objectKey, inviteInfoInDb);
return inviteInfoInDb; return inviteInfoInDb;
} }
@Scheduled(fixedRate = 10000) //定时检测,清理错误的redis数据,防止因为错误数据导致的点播不可用
public void execute(){
String key = VideoManagerConstants.INVITE_PREFIX;
if(redisTemplate.opsForHash().size(key) == 0) {
return;
}
List<Object> values = redisTemplate.opsForHash().values(key);
for (Object value : values) {
InviteInfo inviteInfo = (InviteInfo)value;
if (inviteInfo.getStreamInfo() != null) {
continue;
}
if (inviteInfo.getCreateTime() == null || inviteInfo.getExpirationTime() == 0) {
removeInviteInfo(inviteInfo);
}
long time = inviteInfo.getCreateTime() + inviteInfo.getExpirationTime();
if (System.currentTimeMillis() > time) {
removeInviteInfo(inviteInfo);
}
}
}
} }