本篇博文的目的是告诉大家如何彻底弄清楚resip协议栈的工作流程,resip作为最著名的sip协议栈之一,如果是接触网络媒体通信、网络会议或者是GB28181的同志相当有必要认认真真学习一下resip协议栈。
对于任何一个sip协议栈的学习我们只要弄清楚下面3点,可以说是已经掌握了这个协议栈的骨架了,先把骨架弄清楚再继续学习细节一些的知识点,能节省很多精力。
1、sip信令如何产生?
2、sip信令如何发送?
3、sip信令如何接收,以及接收后怎么处理?
首先对于第一点 "sip 信令如何产生?"
答:sip信令的是通过DialogUsageManager类产生的。
对于第二点"sip信令如何发送?",这应该是resip协议栈比较精华的一部分了,我们将会使用较大篇幅来解释清楚这一点。总的发送流程归结如下:
1、将要发送的消息放置在transportSelector中的FIFO中;
2、将上一步FIFO中的消息移动至transport的FIFO队列中;
3、通过自定义机制判断是否有新消息需要发送,如果有,调用系统sendto()函数发送消息;
上述步骤3中,判断是否有新消息需要发送不是通过系统调用select或者epoll探测,而是通过resip自身的机制判断。(这么做的原因是系统调用多数情况下能够准确判断是否有新消息可收取,但是是否有新消息可发送,系统函数没办法判断,因为他们工作在内核态,对用户态的消息不会十分清楚),其实这个机制也很简单,resip协议栈自定义了类似于select的可读、可写、异常三个状态,如果有新消息产生,就将该状态设置成可写,同时调用select系统调用将系统socket状态设为可写(详见UdpTransport::updateEvents())。至此sip消息就发送出去了。下面我们通过三张流程图彻底体会一下该3步操作:
第一步,将要发送的消息放置在transportSelector中的FIFO中
第二步,将transportSelector的FIFO中的消息移动至transport的FIFO队列中:
第三步:调用系统sendto()函数发送消息
至此我们已经将sip消息的产生和发送的大致框架说清楚了,对于sip消息的接收和接收后的处理,我们放在后续的博文中简绍。