与 UDP HTTP 协议等相比,SIP 协议相对比较“冷门”,但实际生活中还是会接触到,比如你打400电话,或是接到机器人电话,可能背后都有 SIP 的参与。由于笔者水平有限,无法保证都正确,想全面了解 SIP 推荐看官方文档 RFC 3261。
SIP 协议
SIP(Session Initiation Protocol, 会话初始协议)是一种用于在IP网络上建立、修改和终止多媒体会话(如语音通话、视频会议、即时消息等)的信令协议。它主要用于解决在 VoIP(Voice over IP)或其他实时通信应用中,如何建立、管理和终止会话的问题。
特点
- 文本协议,借鉴了 HTTP 协议(头,错误码等)
- 支持 UDP TCP WebSocket 协议作为传输载体
- 对等性,可以不依赖中心服务器进行通讯
- 和其他协议的兼容性,比如:SDP RTP 等等
通过上面的介绍大家对SIP应该有个基础的印象,我们看下实际报文:
INVITE sip:Administrator@192.168.2.218 SIP/2.0
Via: SIP/2.0/UDP 192.168.31.178:62837;branch=z9hG4bK.8WiAEUPjC;rport
From: <sip:alice@192.168.31.178>;tag=4tYbJ32O3
To: sip:Administrator@192.168.2.218
CSeq: 20 INVITE
Call-ID: q~Nno8HNkb
Max-Forwards: 70
Supported: replaces, outbound, gruu, path, record-aware
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, PRACK, UPDATE
Content-Type: application/sdp
Content-Length: 551
Contact: <sip:192.168.2.2:62837;transport=udp>;+org.linphone.specs="conference/1.0,lime"
User-Agent: Linphone-Desktop/5.2.6
v=0
o=alice 3510 667 IN IP4 192.168.31.178
s=Talk
c=IN IP4 192.168.31.178
t=0 0
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics
a=record:off
m=audio 49328 RTP/AVP 96 97 98 0 8 18 101 99 100
a=rtpmap:96 opus/48000/2
a=fmtp:96 useinbandfec=1
a=rtpmap:97 speex/16000
a=fmtp:97 vbr=on
a=rtpmap:98 speex/8000
a=fmtp:98 vbr=on
a=fmtp:18 annexb=yes
a=rtpmap:101 telephone-event/48000
a=rtpmap:99 telephone-event/16000
a=rtpmap:100 telephone-event/8000
a=rtcp:60905
a=rtcp-fb:* trr-int 5000
a=rtcp-fb:* ccm tmmbr
下面我们逐行分析
INVITE sip:Administrator@192.168.2.218 SIP/2.0
INVITE 发起新会话指令,sip:Administrator@192.168.2.218 为目标用户,SIP/2.0表示使用协议SIP/2.0。
Via: SIP/2.0/UDP 192.168.31.178:62837;branch=z9hG4bK.8WiAEUPjC;rport
Via 头部:指示请求的传输路径,SIP/2.0/UDP 192.168.31.178:62837 通过SIP/2.0 UDP协议,经过192.168.31.178:62837。
From: <sip:alice@192.168.31.178>;tag=4tYbJ32O3
From 头部:指示请求的发起者,alice为用户标识,IP为192.168.31.178。
To: sip:Administrator@192.168.2.218
To 头部:表示请求的接收者。sip:Administrator@192.168.2.218 是被呼叫方的 URI。
CSeq: 20 INVITE
CSeq 头部:指示请求的序列号和类型。20 是序列号,INVITE是请求的方法类型。此序列号用于匹配请求和响应,确保它们的顺序。
Call-ID: q~Nno8HNkb
Call-ID 头部:用于唯一标识一个会话。该ID应在整个会话中保持不变。
Max-Forwards: 70
Max-Forwards 头部:指示请求在路由中可以经过的最大代理数量。每经过一个代理,此值减一,达到零时请求会被丢弃。
Supported: replaces, outbound, gruu, path, record-aware
Supported 头部:列出了被请求方支持的特性和扩展,例如:
- replaces:支持会话替换。
- outbound:支持的外出呼叫特性。
- gruu、path、record-aware:其他特性支持。
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, PRACK, UPDATE
Allow 头部:列出发起方支持的方法,表示可以在会话中使用的 SIP 方法。
Content-Type: application/sdp
Content-Type 头部:指示报文体的类型为 SDP(Session Description Protocol),用于描述会话的媒体参数
Content-Length: 551
Content-Length 头部:指示消息体的长度,单位为字节。
Contact: <sip:192.168.2.2:62837;transport=udp>;+org.linphone.specs="conference/1.0,lime"
Contact 头部:提供了可以用来联系发起者的 URI。此处的 URI 是一个可能用于后续通信的地址。+org.linphone.specs 提供了与 Linphone 客户端相关的扩展信息。
User-Agent: Linphone-Desktop/5.2.6
User-Agent 头部:表示发起请求的客户端软件和版本,这里是 Linphone 的桌面版本。
总的来说:alice@192.168.31.178 向 Administrator@192.168.2.218 发起呼叫,SIP 消息body为SDP协议,这里为媒体协商。
对等性
由于SIP支持在UDP传输,UDP本身是无连接的,在网络通的情况可以直接进行呼叫。通常我们用alice呼叫bob做示例,这里我本地Mac为alice@192.168.31.178,目标Windows主机Administrator@192.168.2.218。
呼叫流程:
alice Administrator
| |
| INVITE |
|-------------------->|
| 100 Trying |
|<--------------------|
| 180 Ringing |
|<--------------------|
| 200 OK |
|<--------------------|
| ACK |
|-------------------->|
| |
|<---RTP------------->|
|<---RTP------------->|
|<---RTP------------->|
| ... |
| |
| BYE |
|-------------------->|
| 200 OK |
|-------------------->|
| |
抓个包
- alice 向 Administrator 发起呼叫
- Administrator 响应 100 Trying,表示正常尝试呼叫
- 180 Ringing 表示 Administrator 已响铃
- 200 OK 表示呼叫建立成功
- ACK 确认呼叫建立
- BYE alice 挂机
- 200 OK(BYE) 回应 BYE 指令
背靠背代理
虽然 SIP 可以点对点呼叫,但实际网络环境复杂,除非是局域网内,大多数都是无法完成点对点呼叫(可能涉及 NA T相关),这是需要一个 SIP 代理作为中转。
alice 呼叫 bob,实际先和背靠背代理建立了呼叫,这里是 FreeSWITCH,FreeSWITCH 呼叫 bob,bob 接通电话后,FreeSWITCH 将两通电话桥接起来,这样就实现了 alice 到 bob 的通话。关于 FreeSWITCH 后续文章还会介绍到。
背靠背呼叫流程:
FreeSWITCH
alice (B2BUA Server) bob
| | | |
| INVITE F1 | | |
|------------------->| | |
| 100 Trying F2 | | |
|<-------------------| | INVITE F3 |
| | |------------------->|
| | | 100 Trying F4 |
| | |<-------------------|
| | | 180 Ringing F5 |
| 180 Ringing F6 | |<-------------------|
|<-------------------| | |
| | | 200 OK F7 |
| 200 OK F8 | |<-------------------|
|<-------------------| | ACK F9 |
| ACK F10 | |------------------->|
|------------------->| | |
| RTP Media | | RTP Media |
|<==================>| |<==================>|
| BYE F11 | | |
|------------------->| | BYE F12 |
| 200 OK F13 | |------------------->|
|<-------------------| | 200 OK F14 |
| | |<-------------------|
| | | |
补充
SDP(Session Description Protocol,会话描述协议)是一种用于描述多媒体会话的标准格式。SIP协议消息body即SDP协议,在呼叫中主要用于协商媒体。
RTP(Real-time Transport Protocol,实时传输协议)是一种用于在IP网络上实时传输音频和视频数据的网络协议。SIP确认了会话,SDP确认了语音编码,RTP为实际语音传输。
RTP通常运行在UDP上,相对于丢包,语音对实时性要求更高。