BYE
用BYE方法终止一个媒体会话。在电信领域中,它类似于release消息。会话正式建立的时间点是发送成功应答(2xx)或发出ACK时。只有会话中的UA能发BYE请求,代理或其它第三方网元永远不能发起BYE请求。它是一种端到端的方法,因此应答只能由对端UA生成。如果UA收到未知的BYE请求,那么它应答回应481 Dialog/Transaction Does Not Exist。
如果INVITE还未确立,那么不能用BYE来终止会话,因为它不能像INVITE那样分支处理,最终不能抵达下游所有UA。下面给出一个BYE请求实例:
BYE sip:info@hypotenuse.example.org SIP/2.0
Via: SIP/2.0/TCP port443.hotmail.example.com:54212;branch=z9hG4bK312bc
Max-Forwards:70
To: <sip:info@hypotenuse.example.org>;tag=63124
From: <sip:pythag42@hotmail.example.com>;tag=9341123
Call-ID: 34283291273
CSeq: 47 BYE
Content-Length: 0
下面给出BYE请求的必要头域:
Via |
To |
From |
Call-ID |
CSeq |
Max-Forwards |
ACK
ACK方法用于确认收到INVITE请求的最终应答。其它请求方法不需要确认。最终应答指的是2xx, 3xx, 4xx, 5xx, 或 6xx类的应答。ACK的CSeq序号不变,但方法描述变成ACK。这有助于UAS匹配对应的INVITE事务。
ACK消息可以携带application/sdp消息体。如果初始INVITE没有携带SDP信息,就允许在ACK消息中携带。如果INVITE带了SDP消息体,那么就不应该在ACK消息中携带SDP消息体。不能用ACK方法变更初始INVITE所描述的媒体信息,如果需要变更,必须使用re-INVITE或UPDATE方法。在ACK中携带SDP的方式常用于与其它协议交互的场景,特别是在发初始INVITE时不能获取媒体特征的场景。
对于2xx应答,ACK是端到端的,但对于所有其它最终应答来说,它是逐跳处理的。也就是说,代理在处理转发INVITE请求的3xx, 4xx, 5xx, 或 6xx应答时,会生成ACK。对于2xx应答来说,它的ACK端到端特性能保证消息体的传输。逐跳生成的ACK确认消息中只会包含一条Via头域,说明生成ACK的代理。理解逐跳确认和端到端确认的区别是很重要的。
逐跳确认的ACK请求,使用INVITE请求的同一branch ID,因为它被视为INVITE事务的一部分。但端到端确认的ACK请求不同,它使用的branch ID与INVITE请求所描述的不同,因为它被视为一个新的独立事务。
有状态代理收到ACK消息时,必须判断是否需要向下游代理或UA转发。也就是识别ACK是逐跳的还是端到端的?判断方法就是比较事务的branch ID。如果没有匹配的事务,那么把这条ACK消息向UAS转发。否则,这条ACK就是逐跳确认,不需要转发。下面给出一个带消息体的ACK实例:
ACK sip:laplace@mathematica.example.org SIP/2.0
Via: SIP/2.0/TCP 128.5.2.1:5060;branch=z9hG4bK1834
Max-Forwards:70
To: Marquis de Laplace <sip:laplace@mathematica.example.org> ;tag=90210
From: Nathaniel Bowditch <sip:n.bowditch@salem.example.com> ;tag=887865
Call-ID: 152-45-32-N-32-23-47-W
CSeq: 3 ACK
Content-Type: application/sdp
Content-Length: ...
v=0
o=bowditch 2590844326 2590944532 IN IP4
s=Bearing
c=IN IP4 salem.example.org t=0 0
m=audio 32852 RTP/AVP 96 0
a=rtpmap:96 SPEEX/8000
a=rtpmap:0 PCMU/8000
最后,给出ACK必要的头域:
Via |
To |
From |
Call-ID |
CSeq |
Max-Forwards |