【ZeroRange WebRTC】kvsWebrtcClientMaster 获取 ICE 服务器配置解析
kvsWebrtcClientMaster 获取 ICE 服务器配置解析
本文面向 KVS WebRTC C SDK 的示例程序 ./samples/kvsWebrtcClientMaster,说明它“如何获取 ICE 服务器配置”以及“服务端返回字段的含义与在客户端的映射”。同时结合企业网络穿越与回退策略给出实践建议。
1. 如何获取到的(代码与流程)
- 信令状态机:示例在创建并抓取通道信息后,进入“Get ICE Server Configuration”状态。
- 入口:
executeGetIceConfigSignalingState()(src/source/Signaling/StateMachine.c)。 - 调用:
getIceConfig(pSignalingClient, time)→ 发起到 KVS 的 ICE 配置获取。
- 入口:
- HTTP 调用(REST 管理面):
- 路径常量:
/v1/get-ice-server-config(src/source/Signaling/LwsApiCalls.h的GET_ICE_CONFIG_API_POSTFIX)。 - 构造与签名:
createRequestInfo(...)设置区域、证书、X-Amz-Date与Authorization: AWS4-HMAC-SHA256等 SigV4 头(src/source/Signaling/LwsApiCalls.c)。 - 发送与阻塞完成:通过 LWS 的 HTTPS 客户端角色进行阻塞式调用(日志可见
lwsHttpCallbackRoutine(): Received client http read response)。
- 路径常量:
- JSON 解析与存储:
- 解析键
IceServerList(LwsApiCalls.c中针对IceServerList的标记判断与解析逻辑)。 - 校验并加载到客户端结构,记录诊断时间:
getIceServerConfigStartTime/getIceServerConfigEndTime(Signaling.h)。
- 解析键
- 示例层使用:
- 查询数量:
signalingClientGetIceConfigInfoCount(handle, &count)(src/source/Signaling/Client.c)。 - 逐项获取:
signalingClientGetIceConfigInfo(handle, i, &pIceConfigInfo),随后填充到RtcConfiguration.iceServers。
- 查询数量:
流程摘要:DescribeChannel → GetChannelEndpoint → GetIceServerConfig(HTTPS)→ 解析 IceServerList →(示例)getIceConfigInfo* 读取 → 写入 RtcConfiguration → ICE 候选收集与连通性检查。

2. 服务端字段含义(基于终端日志)
示例日志(节选):
{"IceServerList" : [ {"Password" : "Fe4rEJrNDBE1xj0CVvky8T1HuTCRJvzolWpZjgfu8cs=","Ttl" : 300,"Uris" : ["turn:34-215-147-123.t-ae7dd61a.kinesisvideo.us-west-2.amazonaws.com:443?transport=udp","turns:34-215-147-123.t-ae7dd61a.kinesisvideo.us-west-2.amazonaws.com:443?transport=udp","turns:34-215-147-123.t-ae7dd61a.kinesisvideo.us-west-2.amazonaws.com:443?transport=tcp"],"Username" : "1762846360:..."}, { ... } ]
}
-
为什么不包含 STUN:
- KVS 的
GetIceServerConfig响应只下发 TURN 中继地址与临时凭证;STUN 地址由 SDK 按 Region 本地构造并 DNS 解析,不通过该 JSON 返回。 - 源码依据:
src/source/PeerConnection/PeerConnection.c的resolveStunIceServerIp()根据环境变量/默认区域拼接stun.kinesisvideo.<region>.amazonaws.com(CN 区域使用不同后缀),调用getStunAddr(...)提前解析;日志会打印ICE Server address for <hostname> with getaddrinfo: <ip>。 - 设计原因:STUN 是区域固定的公共服务,独立于通道与凭证;将其本地构造可简化管理面负担并加快解析。TURN 则与通道/时间窗口强绑定,需要凭证与 TTL,因此由服务端按需下发。
- KVS 的
-
IceServerList:ICE 服务器条目数组。示例通常返回多个 TURN 条目,便于容灾与多地址尝试。 -
Uris:该条目的中继地址列表(可含turn:与turns:变体,详见下文)。turn:表示 TURN 控制通道不加 TLS(明文 TCP/UDP);turns:表示 TURN over TLS(控制通道 TLS,加之端口 443,更易穿企业网络/代理)。?transport=udp|tcp表示“中继媒体的承载类型”(relay 的底层传输),与 WebSocket 无关:transport=udp:媒体经 UDP 中继,实时性优于 TCP;transport=tcp:媒体经 TCP/TLS 中继,适合 UDP 全阻环境(延迟更高)。
-
Username/Password:TURN 的临时凭证(Long-Term Credential 风格)。- 含时间戳与通道信息,配合
Ttl(秒)表明有效期;过期必须重新获取。 - 用于 TURN 的 Allocate/Refresh/ChannelData 等交互。
- 含时间戳与通道信息,配合
-
Ttl:凭证与配置的存活时间(秒)。示例中为300秒,超过 TTL 需刷新(SDK 会按需要重新调用 GetIceServerConfig)。
注:在浏览器或 RTCIceServer 结构里常见字段名为 urls/username/credential,而 KVS 服务端原始 JSON 采用 Uris/Username/Password;SDK 做了相应的字段映射。
3. 端口与区域(可达性)
- 统一使用
443:企业网络普遍仅开放80/443的对外访问,把 STUN/TURN 放在443能显著提高穿越率;turns(TLS)还能通过 TLS/SNI 进行合规审计与策略放行。 - 例外说明:
443并不保证 UDP 可用——许多企业只允许TCP/443;此时需回退到turns ... transport=tcp才能保证可达。 - Region 一致性:确保
us-west-2等区域与信令通道一致,减少跨区时延与出网成本。

4. 选择与回退(示例策略)
- 默认(
iceTransportPolicy=ALL):- 优先 host/srflx(直连),失败时选择 relay;relay 中优先
transport=udp,再回退到transport=tcp。
- 优先 host/srflx(直连),失败时选择 relay;relay 中优先
- 强制中继(
iceTransportPolicy=RELAY):- 仅使用 TURN 候选;牺牲直连的低延迟,换取更高成功率(企业网/跨网场景)。
5. 实务建议(针对示例)
- 时钟准确与 TTL:系统时钟需正确;凭证过期时立即重新获取 ICE 配置(SDK 已内置流程)。
- 就近选择与冗余:多条
Uris指向同区域的不同地址,示例会逐项尝试以提升成功率。 - 带宽自适应与可靠性:启用 TWCC/REMB,使用 RTCP NACK/PLI 与短 GOP 提升可恢复性;避免过载导致重传膨胀。
- 资源管理:无人观看尽快释放信令与 TURN 分配,降低中继成本。
6. 关联参考
src/source/Signaling/StateMachine.c:executeGetIceConfigSignalingState()状态入口。src/source/Signaling/LwsApiCalls.c:GET_ICE_CONFIG_API_POSTFIX与请求构造/解析。src/source/Signaling/Client.c:signalingClientGetIceConfigInfoCount/signalingClientGetIceConfigInfo示例层读取。docs/ice-servers-analysis.zh.md:通用 ICE 列表解析与企业网络场景说明。
