![](http://www.ctiforum.com/uploadfile/2019/0410/20190410095024514.jpg)
以上示例仅是一个点对点的呼叫示例,当然,在实际生产环境中,双方呼叫不仅仅是一个点对点的呼叫。在实际生产环境中,大部分呼叫需要经过一个代理服务器来处理。今天,我们结合几个具体的示例重新和大家分享一下比较完整的呼叫流程,看看在呼叫过程中到底发生了多少个Dialog和Transactions。
为了回答这些问题,我们需要首先介绍一下rfc3261的定义细节,然后结合RFC3261规范给出几个示例来解释Dialog和Transactions发送的数量。
因为以前的文章中大量介绍了这些名称的基本概念,我们不再花费时间过多介绍其它完整的概念和相关背景知识。读者可查阅我们的历史文档或者参考RFC3261来进一步了解学习。
1、Call/Session的定义
通常大家所说的SIP call或者call其实在规范中没有非常明确的官方定义,这是一个非常口语化通俗的的说法或表达方式。一般来说,call可以表示为session,一个SIP呼叫至少具有以下几个方面的特点:
- 首先是一个session 会话
- 其次,它必须包括所有的初始,管理和结束会话的所有消息
- 通过Call-ID 头来确认其身份
为了能够让读者完整准确理解我们接下来的讨论,我们使用一个稍微复杂一点的forking呼叫的示例来说明call,dialog和transactions的关系以及呼叫过程中各自的数量。
![](http://www.ctiforum.com/uploadfile/2019/0410/20190410095128677.jpg)
如果我们换一个示例,通过完整的消息流程看到话,表达方式应该是这样的:
![](http://www.ctiforum.com/uploadfile/2019/0410/20190410095155902.jpg)
2、Dialog的定义
关于Dialog的定义,RFC3261是这样定义Dialog的:
A dialog represents a peer-to-peer SIP relationship between two user agents that persists for some time. The dialog facilitates sequencing of messages between the user agents and proper routing of requests between both of them.
https://tools.ietf.org/html/rfc3261#section-12
从定义来看,Dialog本质上说是一种对对点关系的确认。呼叫方UA发起呼叫后,可能导致一个或多个Dialog。Dialog的身份确认通过To tag和From tag组合确认。简单来说,一个Dialog是有本地呼叫方和远端被呼叫方构成。
3、Transaction的定义
关于Transaction的定义我们在前面的文章中有过全面地介绍,另外读者也可以查阅RFC3216来学习。这里,我们重点说明成功呼叫和失败呼叫的Transactions导致的不同处理流程。不同呼叫结果导致不同的事务处理结果,因此,两种Transaction具有以下特点:
成功呼叫的transaction:以一个请求开始,以零个或多个最终响应结束,其中可能包含多个临时响应,ACK除外。
- 失败呼叫的Transaction:包含失败响应消息,ACK包括在了INVITE事务中。
- Transaction通过Via头中的branch参数和CSeq method来确认。
- 仅留存在一个hop中,经过代理处理的请求重新开始一个新的Transaction。
4、关于Dialog数量讨论
根据前面讨论中关于Dialog的定义,结合以下场景,我们知道,场景中产生了2个Dialog。第一个Dialog是A/B之间的Dialog,第二个Dialog是A/C之间的。这两个Dialog通过To tag和From tag 分别绑定了两个终端。因此,以下示例生成了2个Dialog。注意,为了容易让读者了解场景示例,这里的Dialog绑定关系的标识是简单化的标识方式,不是规范的标识。
为了方便理解,很多环境中,我们也把Dialog称之为call-leg。所以,读者不要对其概念产生误解。
![](http://www.ctiforum.com/uploadfile/2019/0410/20190410095446456.jpg)
5、关于Transactions 事务的数量讨论
显然,以上讨论中call和Dialog的数量确认是相对比较简单的,比较复杂的是确认事务的数量。首先说明一下,事务生成的数量取决于多方面的条件和呼叫场景(例如INVITE和非-INVITE事务,客户端和服务器端事务,失败呼叫和成功呼叫的事务,点对点呼叫还是经过proxy代理的呼叫),我们不能完全解释所有的应用环境,因此,笔者现在仅针对相对容易实现,经常使用的场景做示例说明。在介绍场景之前,让我们重新回顾一下关于事务的定义:
a SIP transaction consists of a single request and any responses to that request, which include zero or more provisional responses and one or more final responses.
https://tools.ietf.org/html/rfc3261#section-17
因为我们大部分的业务和INVITE相关,因此,我们重点讨论关于和INVITE相关的事务处理。在RFC3261中,专门针对INVITE请求和Transaction的关系补充了特别说明:
In the case of a transaction where the request was an INVITE (known as an INVITE transaction), the transaction also includes the ACK only if the final response was not a 2xx response. If the response was a 2xx, the ACK is not considered part of the transaction.
https://tools.ietf.org/html/rfc3261#section-17
所以,根据以上说明,读者一定要注意,计算事务生成数量是根据响应消息是 2XX响应还是非2XX响应为基础的。另外,读者需要注意一个问题,为什么ACK有时需要分开处理,并且独立为一个新的事务? 在RFC3261的官方中说明了独立的ACK的根本原因,这是因为ACK涉及到了UAC和UAS直接重传机制的处理。关于重传机制的处理,读者可以查阅RFC3261的13.3.1.4。
下面,我们根据一个常用的分叉呼叫的流程,来分别说明成功呼叫和失败呼叫各自所生成的transaction。以下示例并非按照顺序生成,读者不要误解。
![](http://www.ctiforum.com/uploadfile/2019/0410/20190410095538921.jpg)
根据RFC3261的规范对事务的定义,以上分叉呼叫发生了五个事务处理(Transactions):
- 第一个Transaction发生在呼叫方A 对服务器的请求,是第一个Transaction。
- 第二个Transaction发生于服务器对SIP B的INVITE流程中,因为电话B没有接听,返回了一个487(非2XX)响应,因此紧接着SIP服务器返回了一个ACK。因为是一个失败的呼叫,所以,这个ACK是包含在INVITE中的,因此,这是第二个Transaction。
- 第三个Transaction发生在电话C和服务器端之间。所以,电话C端和服务器端产生了第三个Transaction。另外,因为这是一个成功的呼叫,所以,其响应的ACK是一个独立的Transaction,因此A和C端之间产生了第四个Transaction。ACK在终端之间互相直接通信。
第五个Transaction产生于SIP服务器和电话B之间的失败呼叫中,Cancel是一个独立的Transaction而存在(非INVITE),这是第五个Transaction。
6、三者之间的关系
我们在前面的章节中讨论了call,dialog和transactions的三个SIP呼叫中非常重要的概念,并且对其不同的流程所产生的处理数量做了比较清晰的介绍。
从其概念和实际场景中,我们可以看出其三者之间的关系。简单来说,它们之间的关系是:
- 一个Call可能存在至少一个或者多个Dialogs
- 一个Dialog由一系列多个Transactions事务构成
- Transaction事务各自都是互相独立的
7、总结
在本章节中,笔者重点介绍了SIP 环境中call,Dialog和Transaction的基本概念和其三者之间的关系,并且针对典型的SIP INVITE 呼叫环境下它们各自所生成的数量进行了讨论分析。另外,笔者特别针对比较复杂的事务处理的数量做了非常详细地说明和介绍,并且根据RFC3261对其的定义,对其非2XX响应和2XX响应所产生的事务和独立生成ACK的原因做了解释。
笔者希望通过本章节对事务处理的介绍,帮助读者能够完整了解事务生成的数量和其原因,提高SIP排查技术水平。
补充说明,因为篇幅的关系和时间关系,笔者这里仅介绍了INVITE请求时事务的处理,更多关于其他非INVITE或者其他的事务处理的环境读者需要根据具体的环境来进行进一步学习。
参考资料:
http://www.siptutorial.net/SIP/relation.html
http://www.kamailio.org/docs/tutorials/sip-introduction/#sip_transactions
https://subscription.packtpub.com/book/networking_and_servers/9781849510745/1/ch01lvl1sec13/sip-transactions-and-dialogs
https://arstechnica.com/tech-policy/2010/03/voip-in-depth-an-introduction-to-the-sip-protocol-part-2/
https://www.tech-invite.com/fo-sip/tinv-fo-sip-dialog-05.html
Jae Cheon Han,A study on ACK message processing mechanism in SIP transaction layer
![](http://www.ctiforum.com/uploadfile/2019/0304/20190304034102652.jpg)
![](http://www.ctiforum.com/uploadfile/2019/0304/20190304034119526.jpg)
关注微信公众号:asterisk-cn,获得有价值的Asterisk行业分享
Asterisk freepbx 中文官方论坛:http://bbs.freepbx.cn/forum.php
Asterisk freepbx技术文档: www.freepbx.org.cn
融合通信商业解决方案,协同解决方案首选产品:www.hiastar.com
Asterisk/FreePBX中国合作伙伴,官方qq技术分享群(3000千人):589995817
Asterisk freepbx 中文官方论坛:http://bbs.freepbx.cn/forum.php
Asterisk freepbx技术文档: www.freepbx.org.cn
融合通信商业解决方案,协同解决方案首选产品:www.hiastar.com
Asterisk/FreePBX中国合作伙伴,官方qq技术分享群(3000千人):589995817