Compare commits

...

5 Commits

Author SHA1 Message Date
樊冲
36772969d0
Pre Merge pull request !42 from 樊冲/fix-bug-fanchong 2026-05-28 07:31:56 +00:00
648540858
875c4aed6d
Merge pull request #2161 from Gerrit1999/dev/2159
fix: 修复 issue 2159 级联点播自定义 SSRC 鉴权 key 未刷新问题
2026-05-28 14:50:12 +08:00
lin
2fc63caf13 SSRC管理-加快SSRC重建频率 2026-05-28 14:42:09 +08:00
gerrit
75c38d6c9a
fix: 级联点播下级自定义SSRC后同步刷新RTP鉴权key
当 use-custom-ssrc-for-parent-invite=true 时,下级平台可在 200 OK SDP
中返回自定义 SSRC。此前仅在开收流时按原始 SSRC 写入一次 Redis 鉴权
key,导致 ZLM on_publish 以实际 SSRC 查 Redis 时鉴权失败。

新增 IReceiveRtpServerService.refreshAuthenticateInfo(),在
PlayServiceImpl.InviteOKHandler 解析出最终 SSRC 后,如与原始值不
一致,先刷新 Redis 鉴权 key,再继续现有 SSRC 更新流程。覆盖点播、
回放、下载三种场景。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:29:15 +08:00
樊冲
c543840830 fix: 当wvp作为下级平台时,上级以tcp-主动模式发起点播请求,这个5ms时间太短,下级的zlm刚准备好端口,上级还没来得及连接,zlm就超时端口关闭,导致上级一直报拒绝连接 2025-09-18 17:37:57 +08:00
5 changed files with 28 additions and 6 deletions

View File

@ -859,6 +859,9 @@ public class PlayServiceImpl implements IPlayService {
} }
}else { }else {
log.info("[Invite 200OK] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse); log.info("[Invite 200OK] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse);
String oldStreamId = String.format("%08x", Long.parseLong(ssrcInfo.getSsrc())).toUpperCase();
String newStreamId = String.format("%08x", Long.parseLong(ssrcInResponse)).toUpperCase();
receiveRtpServerService.refreshAuthenticateInfo(oldStreamId, newStreamId);
// ssrc 不一致 // ssrc 不一致
if (mediaServerItem.isRtpEnable()) { if (mediaServerItem.isRtpEnable()) {
// 多端口 // 多端口

View File

@ -50,7 +50,7 @@ public class SSRCFactory {
public void init() { public void init() {
String sipDomain = sipConfig.getDomain(); String sipDomain = sipConfig.getDomain();
domainPart = sipDomain.length() >= 8 ? sipDomain.substring(3, 8) : sipDomain; domainPart = sipDomain.length() >= 8 ? sipDomain.substring(3, 8) : sipDomain;
scheduler.scheduleAtFixedRate(this::rebuild, 10, 30, TimeUnit.SECONDS); scheduler.scheduleAtFixedRate(this::rebuild, 5, 5, TimeUnit.SECONDS);
} }
public String getPlaySsrc(String mediaServerId) { public String getPlaySsrc(String mediaServerId) {
@ -127,12 +127,11 @@ public class SSRCFactory {
usedMap.put(server.getId(), bits); usedMap.put(server.getId(), bits);
if (count > 8000) { if (count > 8000) {
log.info("[SSRC重建] 媒体节点 {} 的SSRC使用率已超过80%,请注意扩展服务提升性能", server.getId()); log.info("[SSRC重建] 媒体节点 {} 的SSRC使用率已超过80%,请注意扩展服务提升性能", server.getId());
} else { }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("[SSRC重建] 节点 {} 已占用 {} 个SSRC", server.getId(), count); log.debug("[SSRC重建] 节点 {} 已占用 {} 个SSRC", server.getId(), count);
} }
} }
} }
} }
}
} }

View File

@ -212,7 +212,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
if (sendRtpItem.isTcpActive()) { if (sendRtpItem.isTcpActive()) {
MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
try { try {
mediaServerService.startSendRtpPassive(mediaServer, sendRtpItem, 5); mediaServerService.startSendRtpPassive(mediaServer, sendRtpItem, 5*1000);
DeviceChannel deviceChannel = deviceChannelService.getOneForSourceById(sendRtpItem.getChannelId()); DeviceChannel deviceChannel = deviceChannelService.getOneForSourceById(sendRtpItem.getChannelId());
if (deviceChannel != null) { if (deviceChannel != null) {
redisCatchStorage.sendPlatformStartPlayMsg(sendRtpItem, deviceChannel, platform); redisCatchStorage.sendPlatformStartPlayMsg(sendRtpItem, deviceChannel, platform);

View File

@ -39,4 +39,6 @@ public interface IReceiveRtpServerService {
void addAuthenticateInfo(String streamId, String streamReplace, Boolean enableAudio, Boolean enableMp4, Integer mp4MaxSecond); void addAuthenticateInfo(String streamId, String streamReplace, Boolean enableAudio, Boolean enableMp4, Integer mp4MaxSecond);
ResultForOnPublish getAuthenticateInfo(String streamId); ResultForOnPublish getAuthenticateInfo(String streamId);
void refreshAuthenticateInfo(String oldStreamId, String newStreamId);
} }

View File

@ -406,4 +406,22 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
} }
return null; return null;
} }
@Override
public void refreshAuthenticateInfo(String oldStreamId, String newStreamId) {
if (oldStreamId == null || newStreamId == null || oldStreamId.equals(newStreamId)) {
return;
}
String oldKey = String.format("%s:%s", VideoManagerConstants.RTP_AUTHENTICATE, oldStreamId);
Object obj = redisTemplate.opsForValue().get(oldKey);
if (obj instanceof ResultForOnPublish) {
String newKey = String.format("%s:%s", VideoManagerConstants.RTP_AUTHENTICATE, newStreamId);
redisTemplate.opsForValue().set(newKey, obj);
redisTemplate.expire(newKey, 60, TimeUnit.SECONDS);
redisTemplate.delete(oldKey);
log.info("[刷新RTP鉴权信息] {} -> {}", oldStreamId, newStreamId);
} else {
log.warn("[刷新RTP鉴权信息] 未找到旧key: {}", oldKey);
}
}
} }