十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Cloudflare TURN 完整实战指南:用 48 小时中继凭证与 ICE 自愈保活 WebRTC 长通话

Cloudflare TURN 完整实战指南:用 48 小时中继凭证与 ICE 自愈保活 WebRTC 长通话 Cloudflare TURN 完整实战指南用 48 小时中继凭证与 ICE 自愈保活 WebRTC 长通话【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills在 WebRTC 生产环境中最典型的隐性故障是通话开了四十多个小时后无声无息地断了。根因往往不是网络而是 Cloudflare TURNTraversal Using Relays around NAT托管中继服务签发的临时凭证过期且无人续期。本文基于 skills 仓库 cloudflare-deploy 模块下 turn 参考文档按拿凭证 → 建连 → 续期 → 自愈 → 观测这条生命周期主线讲清如何把 Cloudflare TURN 做成一套可长期运行的中继方案而不是跑通 Demo 就完事。一张拓扑图讲清楚TURN 在中继链路里扮演什么角色先明确三个角色的分工避免后面每个环节反复解释角色职责你接触它的时机STUNstun.cloudflare.com:3478帮客户端发现自己对公网的候选地址促成直连每次建连成本极低TURNturn.cloudflare.comUDP/TCP/TLS直连被 NAT 或防火墙挡死时流量经 it 中继转发直连失败时的兜底你自己的 Worker用 TURN Key 向凭证端点换取临时凭证再下发给浏览器每个客户端会话开始前关键背景Cloudflare TURN 跑在覆盖 310 城市的全球 anycast 网络上不含中国网络客户端自动落到最近的边缘节点你不需要选区、不需要管服务器列表。费用上有一个重要分叉搭配 Cloudflare Calls SFU 使用时 TURN 免费独立使用则按 $0.05/GB 出站流量计费见 gotchas.md 的成本优化章节。什么时候值得引入 TURN对称型 NAT 挡直连、企业防火墙封 WebRTC 端口、移动网络的运营商级 NAT以及宁可慢一点也要连得上的可预测性场景。反过来纯 P2P 能覆盖的内部网络就别强行上 TURN——iceTransportPolicy的取舍后文再说。决策点一凭证从哪来、活多久TURN 凭证是钥匙派生出的临时密码整条链路的信任边界都在服务端。第一步创建 TURN Key一次性操作POST /accounts/{account_id}/calls/turn_keys # Base URL: https://api.cloudflare.com/client/v4 # 需要 Calls Write 权限的 API Token响应里的key字段只在创建时返回一次丢了无法找回必须当场存进 secrets。后续还有GET列表/详情、PUT改名、DELETE删除四类管理端点详见 api.md。第二步用 Key 换临时凭证POST https://rtc.live.cloudflare.com/v1/turn/keys/{key_id}/credentials/generate Authorization: Bearer {key_secret} { ttl: 86400 }响应核心结构是iceServers.urlsSTUN 与多协议 TURN 地址混合数组、username形如1738035200:user123时间戳前缀即过期信息、credentialBase64 编码的 HMAC。 这里有一条硬约束必须刻进代码TTL 上限 172800 秒48 小时超过会被 API 直接拒绝。很多人写ttl: 6048007 天想一劳永逸结果建连时才发现被拒。正确姿势是TTL 略长于预期会话时长 会话内定时续期而不是拉满上限。第三步把密钥藏进 Worker而不是客户端# wrangler.jsoncTURN_KEY_ID 可放 vars非敏感 # TURN_KEY_SECRET 必须走 wrangler secret put TURN_KEY_SECRET生产环境还可绑定CREDENTIALS_CACHEKV 命名空间做跨请求缓存。Worker 的职责就三件事校验浏览器身份 → 用TURN_KEY_SECRET调生成端点 → 过滤后把临时凭证吐给客户端。完整 Worker 骨架见 configuration.md。为什么密钥绝不下发客户端客户端拿 Key 就等于任何人可以无限免费/计费用你的中继且凭证吊销都拦不住——这是 gotchas.md 安全清单第一条。另外留一个紧急开关POST .../credentials/revokebody 传{username: ...}返回 204计费立即停止、活跃连接数秒内断开。给被攻陷或作恶的会话提供这条吊销通道是生产系统的标配。决策点二端口怎么挑53 端口的隐形地雷凭证 API 返回的urls是全量地址浏览器却只能吃其中一部分顺序地址适用场景1turn:turn.cloudflare.com:3478?transportudp首选延迟最低2turn:turn.cloudflare.com:3478?transporttcpUDP 被封网络的回退3turns:turn.cloudflare.com:5349?transporttcp企业防火墙最可靠4turns:turn.cloudflare.com:443?transporttcp备用 TLS 端口防火墙最友好⚠️ 地雷在这里响应里还混着turn:turn.cloudflare.com:53?transportudp和turn:turn.cloudflare.com:80?transporttcp——非浏览器客户端可用但 Chrome 和 Firefox 会静默拦截 53 端口既不报错也不连接排查时极难察觉。所以过滤逻辑必须放在服务端Worker 返回前而不是指望前端兜底const filteredUrls data.iceServers.urls.filter(url !url.includes(:53));为什么放服务端一旦漏过滤故障只会在某些用户 某些浏览器上随机出现而服务端过滤一次生效全体。仓库示例里还按 UDP 非 TLS TCP TLS 排序保证 ICE 协商优先尝试低延迟路径完整实现见 patterns.md。决策点三建连时让 ICE 替你做选择浏览器端把 STUN 和 TURN 一起交给RTCPeerConnection由 ICE 协商自动择优——直连能通就走直连不通自动降级到 TURN 中继const iceServers await (await fetch(/api/turn-credentials)).json(); // iceServers: [{ urls: stun:stun.cloudflare.com:3478 }, { urls: [...], username, credential }] const pc new RTCPeerConnection({ iceServers });为什么两个都配而不是二选一STUN 成本近乎为零先直连能省 TURN 流量费TURN 是保险丝只在直连失败时真正走流量。同一个接口还能按业务形态调两档策略场景配置行为视频会议iceTransportPolicy: all先 P2P 直连失败才中继默认推荐也省钱IoT / 可预测性优先iceTransportPolicy: relay强制全走 TURN连通性确定屏幕共享等多路流bundlePolicy: max-bundle多路媒体聚合到单条通道降开销如果直接用 Cloudflare Calls SFUTURN 会在需要时自动启用callsClient.createSession({ appId, sessionId })一行建会话无需自己编排 TURN 与 SFU 的协调——顺带解锁了前文说的免费额度。决策点四续期与自愈长通话的生死线这是全文最核心的一段。两个 API 的语义区别决定了你能不能撑过 48 小时pc.setConfiguration()能更新iceServers但不触发 ICE 重启适合凭证还没断、提前换粮pc.restartIce()createOffer({ iceRestart: true })真正重新协商用于连接已经失败后的抢救。续期预防按 TTL 折算刷新间隔提前 1 分钟换凭证TTL 1 小时即 50 分钟一次const refreshInterval ttl * 1000 - 60000; // 提前 1 分钟 setInterval(() refreshTURNCredentials(pc), refreshInterval);为什么提前 1 分钟给网络抖动和请求失败留出重试窗口避免续期请求恰好撞上凭证到期的竞态。自愈抢救iceconnectionstatechange进入failed更稳妥是连disconnected一起兜防移动网络切换掉线时按固定顺序执行刷新凭证 →restartIce()→ 带iceRestart: true重新建 offer → 经信令通道发给对端if (pc.iceConnectionState failed || pc.iceConnectionState disconnected) { await refreshTURNCredentials(pc); const offer await pc.createOffer({ iceRestart: true }); await pc.setLocalDescription(offer); // 经信令发送 offer... }为什么必须这个顺序先换新凭证再重启否则 ICE 重启后拿的还是过期凭证白重启一轮。需要触发这套流程的四种场景TURN 服务器维护、anycast 路由调整、超 1 小时长会话中的凭证刷新、连接进入failed状态。服务端侧还有一个配套动作用TURNCredentialsManager把未过期凭证缓存在内存或 KV命中就复用、未命中才打生成端点并在写缓存时一次性完成 53 端口过滤与ttl 172800防御性校验。模式代码见 patterns.md。为什么缓存高并发下所有客户端共用一份凭证能大幅降低生成端点压力TTL 没到期前它对所有客户端都有效。观测与排障三个 API 一张限额表 一份清单先看流量到底走没走中继——三个观测点组合使用pc.addEventListener(icecandidate, e { if (e.candidate) console.log(e.candidate.type, e.candidate.protocol); // host/srflx/relay }); const stats await pc.getStats(); stats.forEach(r { if (r.type candidate-pair r.selected) console.log(Selected:, r); });icecandidate看候选类型有relay说明 TURN 真正被用上了iceconnectionstatechange跟踪checking → connected → completed或failedgetStats()里selected true的candidate-pair就是当前实际生效的通道——直连还是中继一目了然。丢包时先对照限额。这些限制是按用户分配per-allocation而非账户级维度限额超限后果新唯一 IP 速率5 个/秒丢包包速率入/出 5–10k pps丢包数据速率入/出 50–100 Mbps丢包建连慢时的排查路径候选收集是否完整 → 到 Cloudflare 边缘的延迟 → 防火墙是否放行 3478/5349/443 → 企业网络是否该改用 443 端口的 TURN over TLS。最后是上线前对照清单源自 gotchas.md凭证只在服务端生成密钥绝不下发TURN_KEY_SECRET在 wrangler secrets 而非varsTTL ≤ 预期会话时长且 ≤ 48 小时凭证生成端点有限流 客户端先认证会话被攻陷时可吊销凭证不硬编码 IPIP 有 14 天通知变更期硬编码必炸配 DNS 监控浏览器端 URL 已过滤 53 端口部署边界备忘IPv6、TLS 与企业白名单IPv6客户端到 TURN 支持 IPv4/IPv6 双栈但中继地址只分配 IPv4不支持 RFC 6156TCP 中继RFC 6062也不支持——IPv6 客户端能接入中继流量仍走 IPv4。TLS支持 TLS 1.1/1.2/1.31.3 推荐AEAD-AES128-GCM-SHA256、AEAD-AES256-GCM-SHA384、AEAD-CHACHA20-POLY1305-SHA2561.2 推荐ECDHE-ECDSA-AES128-GCM-SHA256、ECDHE-RSA-AES128-GCM-SHA256等详见 configuration.md。企业 IP 白名单严格防火墙可对turn.cloudflare.com放行 IPv4141.101.90.1/32、162.159.207.1/32与 IPv62a06:98c1:3200::1/128、2606:4700:48::1/128。但 IP 可能提前 14 天通知后变更务必用dig turn.cloudflare.com A / AAAA做自动监控14 天窗口内更新白名单。延伸阅读TURN 服务概览服务地址、端口清单、模块阅读路径TURN API 参考Key 管理、凭证生成/吊销契约、TypeScript 类型、TTL 约束TURN 配置指南Worker 搭建、wrangler.jsonc、环境变量、IP 白名单TURN 实现模式建连、续期、缓存、ICE 重启与调试的完整代码模式TURN 陷阱与排查高频错误、限额、安全清单与故障诊断需要克隆本仓库参考文档时git clone https://link.gitcode.com/i/d7beb73ebdd8cb3b35d85e4b733378d4【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表