STUN
STUN(Session Traversal Utilities for NAT) (这是个通用概念)是一种网络协议,
它的主要作用是帮助设备在NAT(网络地址转换)\或**防火墙后面,
确定自己在公网中的“外部地址”(即公网 IP 和端口),
并协助建立点对点(P2P)连接**。
简单来说,stun服务,你去问他,你的公网IP是多少,然后stun服务会告诉你。【仅此而已】
TURN
TURN(Traversal Using Relays around NAT)(这是个通用概念)是一种中继(中转、转发)服务协议,
用于在点对点(P2P)直连失败时,转发数据。
简单来说,你跟别人通讯,但是由于任意原因,你无法直接和别人构建通讯连接,
这时,turn 服务就作为一个桥梁,跟你、跟别人 分别建立连接,
从而建立你和别人的通讯。
你把信息给turn,turn帮你给别人,同样,别人把信息给turn,turn转给你。
Coturn
Coturn 是一个linux上的软件(服务),它可以提供 stun 以及 turn 服务。
常规 stun 和 turn 都要用到基本的 3478 tcp及udp端口 (参考配置文件中 listening-port 配置项),
除此之外,turn 由于转发时用到随机端口(参考配置文件中 min-port ~ max-port)。
WebRTC
WebRTC(Web Real-Time Communication,网页实时通信)是一套由 W3C 和 IETF 标准化的网页实时通信技术,它允许浏览器和移动端应用无需额外插件或软件,直接进行音视频通话、文件传输和数据通信。
核心目标是 点对点(P2P)实时通信,支持低延迟、多媒体和数据的直接传输。
工作流程
A 获取本地媒体流。
A 创建 RTCPeerConnection。
A 收集 本地候选地址:
- 本地 IP(Host)
- 通过 STUN 获取的公网 IP(Server Reflexive)
- TURN 中继 IP(Relay)
A 创建 SDP Offer,通过信令发送给 B。
B 收到 Offer,收集自己的 ICE 候选地址,同样通过信令返回给 A。
双方尝试:
- 使用本地地址直连(局域网内有效)。
- 使用 STUN 返回的公网地址直连(打洞)。
- 如果直连失败,再使用 TURN 中继。
一旦有路径可以到达对方,P2P 连接建立成功。
音视频流和数据通道开始传输。
SIP
SIP(Session Initiation Protocol, 会话发起协议) 是一种用于建立、修改和终止多媒体会话(音频、视频、即时消息等)的信令协议
工作流程
- 注册阶段
- SIP 终端向 Registrar 发送
REGISTER请求 - 注册自己的位置(IP、端口、用户标识)
- SIP 终端向 Registrar 发送
- 会话建立
- A 端发送
INVITE(含 SDP)给 B 端,通过 Proxy 或直接发送 - B 端响应:
100 Trying:收到请求180 Ringing:振铃200 OK:接听,同时返回 SDP
- A 端发送
ACK确认 - 会话建立,开始 RTP 音视频传输
- A 端发送
- 会话管理
- 可以发送
RE-INVITE修改媒体(如切换视频、共享屏幕) - 也可以发送
OPTIONS查询对方能力
- 可以发送
- 会话终止
- 任意一方发送
BYE - 对方返回
200 OK,会话结束
- 任意一方发送
JSSIP
JsSIP 是一个用 JavaScript 实现的 SIP(Session Initiation Protocol)客户端库,允许网页直接通过浏览器进行 音视频通话 或 即时消息,无需安装任何插件。
工作原理
SIP 信令
- JsSIP 通过 WebSocket (WS/WSS) 连接到 SIP 服务器。
- 发送 SIP 消息(
REGISTER,INVITE,ACK,BYE等)。 - SIP 消息只传递会话控制和 SDP 信息,不传音视频。
WebRTC 媒体传输
- JsSIP 将 SDP 里描述的媒体参数交给 WebRTC。
- WebRTC 建立 P2P 连接,进行音视频流传输。
- 支持 NAT 穿透,自动尝试 STUN/TURN。
信令 + 媒体结合
- SIP 负责呼叫控制(谁打给谁、何时挂断)。
- WebRTC 负责实际音视频流。
- JsSIP 在浏览器端桥接二者,实现纯网页电话。
go2rtc
这是 github 上的一个开源项目,可以把很多视频格式转成 webrtc 格式。
当初认识这个项目,是因为我们有很多网络摄像头,大部分都是 rtsp 视频流,客户有公网查看的需求,于是就有了这么个方案。
rtsp 通过 go2rtc 可以提供 webrtc 协议。
客户访问时,只要调用 go2rtc 提供的接口就可以建立 webrtc 通讯,但是 go2rtc 本身是不暴露到公网的。
所以我们打算开发代理服务,部署在 go2rtc 局域网,跟go2rtc通讯,同时跟我们云端服务通讯,
这样,我们就可以跨公网完成 webrtc 的工作流程。