TURN Server — 是 Traversal Using Relays around NAT 协议的服务器,当两个对等点之间无法建立直接 P2P 连接时,它负责中继两者之间的媒体流量。根据 IETF RFC 5766, 2010,TURN 服务器在 WebRTC 的 ICE 过程中充当最后的后备手段(fallback),即使在对称 NAT 和企业防火墙环境下也能确保连接畅通。
要点概述
TURN Server(Traversal Using Relays around NAT)— 是一种网络服务,定义于 RFC 5766 并在 RFC 8656 中更新,当由于 NAT 或防火墙限制而无法建立直接 P2P 连接时,它在两个客户端之间中继 UDP 和 TCP 流量。在 WebRTC 架构中,TURN 服务器作为最终的备用机制,确保在任何网络条件下都能建立连接。
与 STUN 只告知客户端其外部地址不同,TURN 服务器积极参与数据传输。每个对等点与 TURN 服务器建立连接,并将其媒体数据发送给它。TURN 服务器再将数据转发给另一个对等点。结果是对等点之间没有直接连接——所有流量都经过中继服务器,即使在最严格的 NAT 限制下也能保证送达。
TURN 是 STUN 协议的扩展。TURN 消息使用相同的 20 字节头部和属性机制。关键区别在于 TURN 定义了新的消息类型(Allocate、Refresh、Send、Data、CreatePermission、ChannelBind)以及管理中继分配所需的属性。客户端通过 Allocate 消息在 TURN 服务器上创建分配(allocation),获取中继传输地址(relayed transport address),并使用该地址通过服务器发送和接收数据。
TURN 服务器按照以下步骤序列工作。客户端发送带有身份验证(username、credential)的 Allocate 请求。服务器验证凭据并创建一个分配——将中继地址(TURN 服务器上的 IP:端口)临时绑定到客户端。服务器返回带有 relayed transport address 的 Allocate 响应——其他对等点将通过 TURN 服务器向该客户端发送数据所使用的地址。
创建分配后,客户端可以通过 Send Indication 消息或通过通道(ChannelBind)经由 TURN 服务器发送数据。当从客户端接收数据时,TURN 服务器检查权限(permissions)并将数据中继到目标对等点。为了接收传入数据,客户端必须首先为其期望接收数据的对等点创建权限,否则 TURN 服务器将丢弃传入的数据包。权限通过 CreatePermission 消息指定对等点的 IP 地址来创建。
TURN 服务器上的分配具有有限的生存时间——默认为 10 分钟。客户端必须定期发送 Refresh 请求以延长分配。生存时间以秒为单位在 LIFETIME 属性中指定。如果没有 Refresh,服务器将删除分配并释放中继地址。建议的刷新间隔为 5 分钟(300 秒),以防止 Refresh 数据包丢失。
在 WebRTC 中,TURN 服务器通过 RTCPeerConnection 配置中的 iceServers 数组进行配置。TURN 服务器可以使用 UDP、TCP 或 TLS 传输。身份验证通常使用在应用服务器上生成且具有有限有效期的临时凭据(TURN credentials)。
让我们看一个在 JavaScript 中通过 HMAC-SHA1 令牌进行身份验证的 TURN 服务器配置示例。
async function createPeerConnection(turnServerUrl) {
const credentials = await fetchTurnCredentials();
const config = {
iceServers: [
{
urls: "stun:stun.l.google.com:19302"
},
{
urls: turnServerUrl,
username: credentials.username,
credential: credentials.credential
}
],
iceTransportPolicy: "all"
};
return new RTCPeerConnection(config);
}
async function fetchTurnCredentials() {
const response = await fetch("/api/turn-credentials");
return response.json();
}
const turnUrl = "turn:turn.example.com:3478";
const pc = await createPeerConnection(turnUrl);
在此示例中,TURN 服务器与 STUN 服务器一起在统一的 ICE 配置中指定。ICE 过程将首先尝试 host 候选者以及从 STUN 获取的 srflx 候选者。如果无法建立直接连接,ICE 将自动切换到从 TURN 服务器获取的 relay 候选者。参数 iceTransportPolicy: "all" 允许 relay 候选者——替代值 "relay" 禁止除 TURN 之外的任何候选者,这有助于测试。
为防止未经授权的使用,TURN 服务器需要身份验证。标准方法是使用在应用服务器上通过 HMAC-SHA1 生成的限时凭据(time-limited credentials)。应用服务器使用 TURN 服务器的密钥加密用户名,并将 username 和 credential 返回给客户端。客户端将它们传递给 RTCPeerConnection 配置,浏览器在 TURN 服务器上创建分配时使用它们。凭据过期后,客户端从应用服务器获取新凭据。
TURN 和 STUN 解决类似的 NAT 穿越问题,但在机制和成本上有根本区别。TURN 中继流量,充当中介,而 STUN 仅帮助确定外部地址以建立直接 P2P 连接。两者之间的选择取决于对等点的 NAT 类型和性能要求。
| 标准 | STUN | TURN |
|---|---|---|
| 机制 | 确定外部地址 | 中继流量 |
| 连接 | 直接 P2P | 通过中继服务器 |
| 延迟 | 最小(直接路由) | 额外(通过中继器) |
| 服务器负载 | 仅初始请求 | 持续中继流量 |
| 成本 | 低(少量请求) | 高(服务器上的流量) |
| 与对称 NAT 的兼容性 | 否 | 是 |
| 带宽 | 仅限 P2P 通道限制 | 服务器通道限制 |
在实践中,TURN 服务器仅用于 P2P 不可行的连接。根据 Google 的数据(WebRTC statistics, 2023),约 15–20% 的 WebRTC 连接需要 TURN 中继。其余 80–85% 通过 STUN 或本地 host 候选者建立。在设计应用程序时,如果受众包括来自企业网络和 NAT 限制严格区域的用户,应预留 TURN 流量预算,约为总媒体数据量的 15–20%。
TURN 服务器消耗大量资源,因为所有媒体流量都经过它。每个使用 TURN 中继的活动通话都会占用相当于媒体流量总带宽(传入 + 传出流)的服务器带宽。对于高清(720p)视频通话,每个方向可能需要 1.5–2.5 Mbps,即通过 TURN 服务器的总流量为 3–5 Mbps。
部署 TURN 基础设施有几种选择。免费的公共 TURN 服务器不推荐用于生产环境,因为缺乏质量和安全保障。商业提供商(Twilio Network Traversal Service、Xirsys、Metered)提供按流量付费的 TURN 服务——典型成本为每 GB $0.005–0.02。基于 coturn(开源 TURN 服务器)的独立部署需要具有足够带宽的服务器和监控配置。
在选择 TURN 服务器解决方案时,应考虑用户地理位置、流量成本和安全性要求。对于拥有数千个并发通话的应用程序,在带宽充足(1+ Gbps)的服务器上自托管 coturn 可能比商业提供商更经济。对于只有几十个用户的小型项目,商业 TURN 服务由于无需管理和监控成本而更受欢迎。
常见问题
TURN 服务器是一个中介,当用户之间无法直接连接时,它在用户之间传输数据。如果两台计算机位于不允许直接连接的路由器后面,TURN 服务器从一台接收数据并发送给另一台。
当 WebRTC 通话的双方都位于对称 NAT 或阻止 P2P 流量的企业防火墙后面时,需要 TURN 服务器。在这种情况下,STUN 无法提供帮助,ICE 过程会自动切换到从 TURN 服务器获取的中继候选者。
STUN 只是向计算机显示其外部地址以进行直接连接。TURN 主动通过自身中继流量。STUN 不会在服务器上产生负载,TURN 会消耗带宽。STUN 仅适用于特定类型的 NAT,TURN 始终有效但成本更高。
TURN 服务器的成本取决于提供商和流量大小。Twilio 对通过 TURN 的流量收取约 $0.005–0.01/GB。Xirsys 从 $0.007/GB 起。独立部署 coturn 需要带宽至少为 100 Mbps 的服务器,其成本取决于托管提供商。
自己的 TURN 服务器使用 coturn(开源)进行配置。安装包括端口、身份验证(shared secret)、TLS 证书和防火墙的配置。基本配置文件包含 listening-port、realm、user 和 fingerprint 参数。配置后,服务器在 WebRTC 的 iceServers 中以 turn: 或 turns:(用于 TLS)前缀指定。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。