若是你对Sip协议中Call, Dialog, Transaction和Message之间的关系感受到迷惑,那么,那么我能够告诉你,你并不孤单,由于大多数初学者对于这些名词之间的关系都会感到疑惑.服务器
呼叫(call): 呼叫是一个非正式的术语,用来表示一个多媒体会话,用Call-ID来标识;不论两方通话仍是在多方通话中,在每一个UA中是使用同一个Call-ID;网络
事务(transaction): 请求(UAC)+最终响应(相邻的UAS),SIP基于事务。所谓相邻就是说transaction存在于相邻的SIP实体,而不是存在于两个UA之间。CSeq标识。一个事务中包含一个请求消息、0个或多个临时响应消息、1个或多个最终响应消息(2xx~6xx)。SIP是事务性的协议。事务的区分经过Via字段栈顶的Branch的值来肯定,这是因为对于请求消息每通过一个有事务状态的Proxy的时候,该Proxy须要为这个事务建立一个服务器端事务和一个客户端事务,而且将本身的URI添加到Via的栈顶,并生成一个Global ID作为Branch的值,以此值来表示一个与之相对应的事务。SIP在事务层面定义了状态机和定时器来实现重传。session
下图是一个回复200 OK的成功的INVITE事务:是否是INVITE事务区别在于 UAC须要为每一个INVITE最终请求(2xx~6xx)生成ACK响应,而其余的请求消息(INFO,OPTION,etc)则没必要如此。由于INVITE的地位比较重要, 因此须要这样一个三次握手的机制来保证会话的双方都可以确保事务的完整性,这一点和TCP链接创建的三次握手比较像。ide
注意在上图这两个UA中,每个代理服务器都将本身的地址加入返回的ACK的Via头域中,而非成功的transaction则不会加入,见RFC 3261 (p.24)。CSeq头域的值必须与INVITE相同,而且CSeq的方法必须是ACK。中间响应消息 1xx 的使用则是为了节省网络开销设计的,一旦 UC 收到任何一个中间响应消息,则 UC 必须中止消息重发定时器,再也不从发这个请求消息,反之则直到收到最终响应消息或重发定时器超时。一旦客户端UAC的事务在Calling状态收到任何中间响应消息1xx,事务则自动切换到Processing状态,中止请求消息的重发。而且须要将中间响应消息传送给TU事务用户。在呼叫业务中,TU以及上层应用能够根据中间响应消息在用户界面上提示用户。一旦事务切换到Processing状态,任何其余中间响应消息也都要传送给TU。.net
而非INVITE事务则以下:翻译
当UAC发出非INVITE请求时,它就会在事务管理子层上开启定时器F(TCP)或者是E(UDP),确保超时的时候进行重传。这适用于除了 ACK请求外的其余非INVITE请求。每次超时重传时E的时间都被翻倍,直到最大的4秒。而F超时时,UAC就会认为是Timeout,这个事务将被删除。设计
对话(dialog/leg): 表明着两个SIP UA之间持续一段时间的端到端的联系(如:一段通话)。也就说仅仅存在于端到端的信令关系。当一个UAS发出对于INVITE(或者REFER)的非失败最终响应<=>200OK(BYE),则Dialog创建,同时这也是session的开始。UA和SIP代理服务器之间不会有对话。在SIP中呼叫中包含一个或多个Dialog(这仅仅存在于多方通话中)。Dialog终结于任意一端发出 BYE。Early Dialog能够经过UAC发出的CANCEL进行终结,更确切的说,全部早期对话在接收到非2XX最终响应时就被终结了。 Call-ID-value、To、From进行标识。Forking时体现明显。代理
在这个Forking的例子中,这个用户注册了三个设备,在用户被呼叫时,INVITE的Contact头域就被转换为三个INVITE发往三个设备。后边的q指的是优先级,q越小,优先级越高。其中的SIP注册服务器至关于一个Forking代理,尽管这个实体接收到两个ACK,可是除了这些ACK外,它与主叫方的信令交互都是属于一个transaction的,而与被叫方则分别创建了Transaction。另外,被叫方收到的两个ACK由分别创建了Transaction。注意Device3返回了488这样的非成功响应,SIP注册服务器(Forking代理服务器)没有将该响应发回主叫方,这是SIP代理一个重要的特征,SIP代理还能自行发出Request:CANCEL消息。blog
UAS对话层接收到一个新的对话请求INVITE消息后,在创建会话的响应消息2xx中,将请求消息里面的全部Route-Record字段拷贝到2xx消息中,而且UAS的对话层必须添加一个Contact字段使得对话中后续的响应(INVITE在2xx响应的状况下也包括ACK消息)、请求消息能够直接和本UA联系。当UAC收到UAS的INVITE的2xx响应消息后,若是2xx中不包含任何Route-Record字段的,则UAC能够选择直接发送ACK到Contact中地址&端口。three
会话(session): 多方用户的媒体关系,在对话的控制下创建。
下图是Early dialog、Session、Dialog、Transaction等的在一个UA-UA的呼叫中的体现:
在这个例子中,经过INVITE事务而成功创建起来的dialog必须有一个ACK进行回应,这是第二个transaction的开始,尽管ACK并无回复,可是因为新的 branch-value被填入,因此这个ACK表明了一个新的Transaction的开始。注意,此时 transaction number (CSeq) 并无根据INVITE而增长--也就是说若收到的最终响应不是2XX(是3XX--6XX),则该transaction中包含ACK,若最终响应是2XX,则ACK属于一个新的transaction(此处存疑,国外有资料将其视为一个新的transaction,可是RFC3261中的意思倒是ACK不属于INVITE Transaction,也不建立新的Transaction,但会从新计算Transaction参数--branchID)。早期对话是UAS以一个1XX响应做为回应时创建的。这样作的好处是在UAC可能在早期对话中发出诸如UPDATE这样的SIP请求。