问题描述
新疆移动华为HMS平台使用302重定向进行RTSP负载均衡。入口服务器(HWServer)根据频道ID将请求分发到不同的流媒体服务器(HMS_V1R2节点)。
部分HMS节点在某些情况下会在RTSP握手阶段直接断开连接(DESCRIBE后 "Server closed connection"),不返回302也不返回SDP。rtp2httpd原版遇到这种情况直接放弃,返回503,导致该频道播放失败。
实际现象:
- 同一个频道,第一次请求拿到HMS节点A,A断开连接 → 播放失败
- 重新请求,入口服务器分配HMS节点B,B正常 → 播放成功
- 说明问题出在没有重试机制,而不是频道本身不可用
建议的解决方案
在RTSP重定向后的HMS服务器握手断开时,自动回退到原始入口服务器重新获取重定向,最多重试3次。每次重试可能拿到不同的(可用的)HMS节点。
需要修改的文件
1. src/rtsp.h — session结构体新增两个字段:
redirect_retry_count:当前重试次数
original_server_url:原始入口服务器URL(重试时回退的目标)
2. src/rtsp.c — 核心修改:
- 新增宏
RTSP_MAX_REDIRECT_RETRIES 3
rtsp_session_init 中初始化新字段
- 在
rtsp_handle_socket_event 的 POLLER_HUP | POLLER_ERR | POLLER_RDHUP 处理分支中(约966行),设置 RTSP_STATE_ERROR 之前插入重试逻辑:
if (session->redirect_count > 0 &&
session->redirect_retry_count < RTSP_MAX_REDIRECT_RETRIES &&
session->original_server_url[0] != 0 &&
session->state != RTSP_STATE_PLAYING &&
session->state != RTSP_STATE_SENDING_TEARDOWN &&
session->state != RTSP_STATE_AWAITING_TEARDOWN &&
session->state != RTSP_STATE_TEARDOWN_COMPLETE) {
session->redirect_retry_count++;
// 关闭当前socket,重置redirect_count/cseq/session_id
// 重新调用rtsp_parse_server_url(session, session->original_server_url, ...)
// 重新调用rtsp_connect(session)
return 0; // 重试进行中
}
3. src/stream.c — RTSP session初始化后保存原始入口URL到 original_server_url
重试条件说明
- 仅在已经发生过重定向(
redirect_count > 0)时才触发重试
- 最多重试3次
- 仅在非播放中/非teardown状态时重试,避免影响正常播放的连接
- 重试时关闭当前socket,重置会话状态,重新走一遍连接+重定向流程
验证结果
该修复已在新疆移动IPTV环境下实际编译运行验证,效果良好。之前频繁出现的"部分频道偶尔播放失败"问题得到解决。
环境信息
- 运营商:新疆移动IPTV
- 入口服务器:117.146.223.183:554(HWServer)
- 流媒体服务器:211.138.33.x / 117.146.22.x 等(HMS_V1R2)
- 协议:RTSP单播拉流(非组播)
- 操作系统:Linux x86_64 / ImmortalWrt
希望能考虑将这个修复合并到主分支,谢谢!
问题描述
新疆移动华为HMS平台使用302重定向进行RTSP负载均衡。入口服务器(HWServer)根据频道ID将请求分发到不同的流媒体服务器(HMS_V1R2节点)。
部分HMS节点在某些情况下会在RTSP握手阶段直接断开连接(DESCRIBE后 "Server closed connection"),不返回302也不返回SDP。rtp2httpd原版遇到这种情况直接放弃,返回503,导致该频道播放失败。
实际现象:
建议的解决方案
在RTSP重定向后的HMS服务器握手断开时,自动回退到原始入口服务器重新获取重定向,最多重试3次。每次重试可能拿到不同的(可用的)HMS节点。
需要修改的文件
1.
src/rtsp.h— session结构体新增两个字段:redirect_retry_count:当前重试次数original_server_url:原始入口服务器URL(重试时回退的目标)2.
src/rtsp.c— 核心修改:RTSP_MAX_REDIRECT_RETRIES 3rtsp_session_init中初始化新字段rtsp_handle_socket_event的POLLER_HUP | POLLER_ERR | POLLER_RDHUP处理分支中(约966行),设置RTSP_STATE_ERROR之前插入重试逻辑:3.
src/stream.c— RTSP session初始化后保存原始入口URL到original_server_url重试条件说明
redirect_count > 0)时才触发重试验证结果
该修复已在新疆移动IPTV环境下实际编译运行验证,效果良好。之前频繁出现的"部分频道偶尔播放失败"问题得到解决。
环境信息
希望能考虑将这个修复合并到主分支,谢谢!