关闭

pjsip消息在模块与实例间的流动

标签: applicationuserbranchnull
842人阅读 评论(0) 收藏 举报
分类:

一个模块会有多个实例,模块更像一个部门,而实例就是部门里的人。比如user_agent模块中有多个dlg实例。目前涉及的模块优先级有高到低依次是transaction, user_agent(dlg),mod_inv(inv), application。 

首先,每隔模块都有一个回调函数on_rx_request(), 该函数返回bool型的值,表示该模块是否处理了该数据。当收到消息时,endpoint会依次按模块优先级把消息传给注册到该endpoint上模块,直到有个模块返回ture为止。 比如user_agent模块的on_rx_request()返回true后,该消息就不会由endpoint传给mod_inv模块和application模块了;当然有可能会由user_agent模块中的dlg实例传给mod_inv模块中的某个inv实例(dlg和inv一一对应)。 以上可阅读《pjsip_dev_guide》。 

下面以第一次收到request(数据为rdata)为例(也就是说消息会传到application模块), 说明各个模块和实例间消息的流动。 首先,endpoint收到消息后先传给模块transaction,注意是模块。 transaction模块有个哈希表,保存了所有的transaction实例。transction模块首先根据rdata计算出一个key,如果transtation模块有rdata对应的transaction实例,可以通过这个key得到。 如果该消息时符合rfc3261的,那么key是由branch参数计算的来的,而branch参数是可以唯一标示某个transaction实例的。如果消息时符合rfc2543的,这个key则由唯一标识transaction实例的数据得来。总之,这个key和transaction实例是一一对应的, 不管transaction模块中有没有对应的transaction实例。如果找到对应的transaction实例(还要求该transaction没处于terminated的状态,以后只说明主要流程,这类细节不在详述),transaction模块的on_rx_request()将返回true,endpoint将停止对消息的传送, 接下来由对应的transaction实例传送消息。transaction实例怎么传送消息,后面再做论述。 

按前面的假设,transaction模块没找到对应的transaction实例,transaction模块的on_rx_request()将返回false,消息将再传给user_agent模块。user_agent模块和transaction模块有些类似,也有自己的hash表来保存现有的dlg实例。同样的,user_agent也会根据rdata中的 数据(比如from tag, to tag)计算出key来查找有无对应的dlg。dlg实例传送消息和transaction实例类似,也在后面论述。同样的,user_agent模块的on_rx_request()也返回false,消息传到mod_inv模块。mod_inv模块位于pjsip中的pjsip_ua项目,它只接受来自dlg实例的请求,即它会根据rdata中endpt_info中的mod_data[mod_ua.id]中对应dlg的指针是否为NULL,判断是否返回false。如果为NULL,则返回false。至于为什么根据mod_data[mod_ua.id]来判断,后面再介绍。如果该指针不为NULL,mod_inv模块并不立刻返回true,而再根据rdata中的method等条件判断,具体的这里不再详述。

在本例中,那个指针为NULL,mod_inv模块的on_rx_request()将返回false。 最后,endpoint将消息传到application模块。application模块是开发者自己写的,其on_rx_request()的返回值自己判断,如果还是返回false,endpoint的行为我还没看,以后再介绍。估计是丢弃消息,或是返回5xx消息。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1195次
    • 积分:26
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档