【ZeroRange WebRTC】Kinesis Video Streams WebRTC Data Plane WebSocket API 深度解析
Kinesis Video Streams WebRTC Data Plane WebSocket API 深度解析
基于官方文档与 amazon-kinesis-video-streams-webrtc-sdk-c-main 源码(v1.7.0+)
1. 职责定位
| 维度 | 说明 |
|---|---|
| 所属平面 | Data Plane WebSocket(信令数据面) |
| 主要用途 | 1. 建立 Master/Viewer 会话长连接 2. 实时交换 SDP Offer/Answer 3. 收发 ICE Candidate(Trickle) 4. 下发控制信令(Go Away、Reconnect Ice Server) |
| 协议 | WebSocket over TLS(WSS) |
| 鉴权 | 预签名 URL(X-Amz-ChannelARN、X-Amz-ClientId 等 Query 参数) |
| 消息格式 | JSON,UTF-8,每条消息 ≤ 10 KiB |
| 并发模型 | 每通道仅 1 个 Master + N 个 Viewer(默认 10,可调) |
2. 端到端交互时序
3. 连接握手细节
3.1 端点拼装
- 模板定义(src/source/Signaling/LwsApiCalls.h:97-98)
#define SIGNALING_ENDPOINT_MASTER_URL_WSS_TEMPLATE \"%s?%s=%s" // baseWssUrl?X-Amz-ChannelARN=...
#define SIGNALING_ENDPOINT_VIEWER_URL_WSS_TEMPLATE \"%s?%s=%s&%s=%s" // + &X-Amz-ClientId=...
- 代码拼装(src/source/Signaling/LwsApiCalls.c:1463-1469)
if (role == VIEWER) {SNPRINTF(url, ARRAY_SIZE(url),SIGNALING_ENDPOINT_VIEWER_URL_WSS_TEMPLATE,pSignalingClient->channelEndpointWss,SIGNALING_CHANNEL_ARN_PARAM_NAME,pSignalingClient->channelDescription.channelArn,SIGNALING_CLIENT_ID_PARAM_NAME,pSignalingClient->clientInfo.signalingClientInfo.clientId);
} else { // MASTERSNPRINTF(url, ARRAY_SIZE(url),SIGNALING_ENDPOINT_MASTER_URL_WSS_TEMPLATE,pSignalingClient->channelEndpointWss,SIGNALING_CHANNEL_ARN_PARAM_NAME,pSignalingClient->channelDescription.channelArn);
}
3.2 TLS & 预签名
- 使用
HTTPS证书链校验;根证书由系统 CA 提供。 - Query 参数已包含 SigV4 预签名,服务端校验时间戳、签名、过期(默认 15 min)。
- SDK 内部复用
createRequestInfo()统一注入AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN(若使用临时凭证)。
4. 消息格式
4.1 发送模板(src/source/Signaling/LwsApiCalls.h:115-129)
// 基础版
{"action": "SDP_OFFER|SDP_ANSWER|ICE_CANDIDATE|...","RecipientClientId": "<peer id>","MessagePayload": "<Base64Encoded>"
}// 带 CorrelationId(用于同步等待 STATUS_RESPONSE)
{"action": "...","RecipientClientId": "...","MessagePayload": "...","CorrelationId": "<uuid>"
}
MessagePayload长度 ≤ 10 KiB(UTF-8 编码后)。- 若消息类型为
SDP_OFFER且本地已获取IceServerList,SDK 会追加IceServerList字段(供对端使用)。
4.2 接收格式
{"action": "SDP_OFFER|SDP_ANSWER|ICE_CANDIDATE|GO_AWAY|RECONNECT_ICE_SERVER|STATUS_RESPONSE","SenderClientId": "<from>", // 仅接收时存在"MessagePayload": "<Base64>","CorrelationId": "<uuid>", // 可选"Status": "200|403|404|..." // 仅 STATUS_RESPONSE
}
5. 代码调用链路
5.1 连接建立
// 状态机:SIGNALING_STATE_CONNECT
connectSignalingChannel()
└─ connectSignalingChannelLws() // src/source/Signaling/LwsApiCalls.c:1445├─ lws_client_connect_via_info() // libwebsockets└─ 等待 LWS_CALLBACK_CLIENT_ESTABLISHED
5.2 发送消息
// 应用线程
signalingClientSendMessageSync()
└─ writeLwsData() // 原子写入缓冲区└─ lws_callback_on_writable() // 唤醒 LWS 线程
// LWS 线程回调
lwsWssCallbackRoutine(LWS_CALLBACK_CLIENT_WRITEABLE)
└─ lws_write()
5.3 接收消息
lwsWssCallbackRoutine(LWS_CALLBACK_CLIENT_RECEIVE)
├─ jsmn_parse() // 解析 JSON
├─ getMessageTypeFromString() // 转枚举
├─ receiveLwsMessageWrapper() // 异步投递工作线程
└─ 用户回调 messageReceivedFn
6. 状态机与错误处理
| 回调原因 | SDK 动作 | 日志关键词 |
|---|---|---|
LWS_CALLBACK_CLIENT_ESTABLISHED | 设置 connected=TRUE,广播 connectedCvar | Connection established |
LWS_CALLBACK_CLIENT_CONNECTION_ERROR | 设置 connected=FALSE,启动 reconnectHandler 线程 | Client connection failed |
LWS_CALLBACK_CLIENT_CLOSED | 同上 | WSS callback ... closed |
LWS_CALLBACK_WS_PEER_INITIATED_CLOSE | 记录关闭码 | Peer initiated close with code |
- 重连线程指数退避:初始 100 ms → 最大 30 s;退避因子 1.5。
- 退避期间保持
WSS协议级 Ping/Pong(默认 30 s 间隔)。
7. 关键日志与快速检索
# 连接
grep -n "Connection established\|Client connection failed" master.log# 消息收发
grep -n "Sending data over web socket\|Received message type" master.log# 关闭/重连
grep -n "WSS callback.*closed\|Reconnect attempt" master.log
8. 性能与限制
| 项目 | 默认值/上限 | 说明 |
|---|---|---|
| 单通道 Viewer 数 | 10 | 可在控制面提高配额 |
| 消息大小 | 10 KiB | 含 Base64 后的 JSON |
| 连接空闲超时 | 60 s | 服务端主动断开 |
| Ping/Pong 间隔 | 30 s | 保活,可配置 |
| 重连退避 | 100 ms → 30 s | 指数 1.5x |
9. 常见错误码与排错
| HTTP Status | 含义 | 排查要点 |
|---|---|---|
| 400 InvalidArgument | 参数非法 | 检查 ARN、ClientId 格式与长度 |
| 403 AccessDenied | 签名/权限失败 | 时钟偏差 < 5 min;IAM 策略是否允许 kinesisvideo:ConnectAsViewer/ConnectAsMaster |
| 404 ResourceNotFound | 通道不存在 | ARN 区域与端点一致;通道是否被删除 |
| 400 ClientLimitExceeded | 超限 | Viewer 数超配额;API 速率超限(默认 100 TPS) |
| 1000/1001 正常关闭 | - | 无需处理;重连即可 |
10. 小结
- 职责:WebSocket 数据面仅负责会话级信令,不承载媒体与配置。
- 安全:TLS + 预签名 URL,短期凭证,独立限流。
- 可靠:指数退避重连、Ping/Pong 保活、消息 ACK(CorrelationId)。
- 易用:JSON 透明格式,与标准 WebRTC 信令对齐;SDK 封装发送/接收/重连细节。
掌握连接 URL 拼装、消息模板、回调处理与重连策略,即可快速定位信令层问题。
