apt_poller_tas.apt_poller_task_run–> mrcp_client_connection.mrcp_client_poller_signal_process–> 
sendrecv.apr_socket_recv –> 
mrcp_stream.mrcp_parser_run –> 
mrcp_client_connection.mrcp_client_message_handler–> 
mrcp_client_connection.mrcp_connection_channel_find–> 
mrcp_connection_types.mrcp_connection_message_receive–> 
mrcp_client.mrcp_client_message_signal–> 
mrcp_client.mrcp_client_connection_task_msg_signal–> 
apt_task.apt_task_msg_signal–> 
apt_consumer_task.apt_consumer_task_msg_signal–> 
apr_queue.apr_queue_push

pt_poller_task_run是一个无线循环,会不断调用mrcp_client_poller_signal_process()函数,在mrcp_client_poller_signal_process()中,会通过apr_socket_recv函数在socket上阻塞等待数据,然后通过mrcp_parser_run解析接收到的数据包。 
这个函数的实现我在博文freeswitch mrcp 源码分析–数据解析已经进行了详细介绍。

数据解析完成后会调用mrcp_client_message_handler处理接收到的数据, 
在mrcp_client_message_handler中先调用mrcp_connection_channel_find通过通道编码找到对应的通道,然后调用mrcp_connection_message_receiv处理接收到的数据。

mrcp_connection_message_receive的代码如下。可以看到主要是调用了vtable->on_receive。

static APR_INLINE apt_bool_t mrcp_connection_message_receive(
                        const mrcp_connection_event_vtable_t *vtable,
                        mrcp_control_channel_t *channel, 
                        mrcp_message_t *message)
{
    if(vtable && vtable->on_receive) {
        return vtable->on_receive(channel,message);
    }
    return FALSE;
}

vtable是一个mrcp_connection_event_vtable_t对象:

static const mrcp_connection_event_vtable_t connection_method_vtable = {
    mrcp_client_channel_add_signal,
    mrcp_client_channel_modify_signal,
    mrcp_client_channel_remove_signal,
    mrcp_client_message_signal,
    mrcp_client_disconnect_signal
};

所以会执行mrcp_client_message_signal函数,进而调用mrcp_client_connection_task_msg_signal,简单组装参数后会调用apt_task_msg_signal,

APT_DECLARE(apt_bool_t) apt_task_msg_signal(apt_task_t *task, apt_task_msg_t *msg)
{
    apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Message to [%s] ["APT_PTR_FMT";%d;%d]",
        task->name, msg, msg->type, msg->sub_type);
    if(task->vtable.signal_msg) {
        if(task->vtable.signal_msg(task,msg) == TRUE) {
            return TRUE;
        }
    }

apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Task Message [%s] [0x%x;%d;%d]",
        task->name, msg, msg->type, msg->sub_type);
    apt_task_msg_release(msg);
    return FALSE;
}

所以主要调用了task->vtable.signal_msg函数,这里task是一个apt_task_t结构图,在创建的时候signal_msg被赋值为apt_consumer_task_msg_signal:

APT_DECLARE(apt_consumer_task_t*) apt_consumer_task_create(
                                    void *obj,
                                    apt_task_msg_pool_t *msg_pool,
                                    apr_pool_t *pool)
{
    apt_task_vtable_t *vtable;
    apt_consumer_task_t *consumer_task = apr_palloc(pool,sizeof(apt_consumer_task_t));
    consumer_task->obj = obj;
    consumer_task->msg_queue = NULL;
    if(apr_queue_create(&consumer_task->msg_queue,1024,pool) != APR_SUCCESS) {
        return NULL;
    }

consumer_task->base = apt_task_create(consumer_task,msg_pool,pool);
    if(!consumer_task->base) {
        return NULL;
    }

vtable = apt_task_vtable_get(consumer_task->base);
    if(vtable) {
        vtable->run = apt_consumer_task_run;
        vtable->signal_msg = apt_consumer_task_msg_signal;
    }

#if APR_HAS_QUEUE_TIMEOUT
    consumer_task->timer_queue = apt_timer_queue_create(pool);
#endif

return consumer_task;
}

在apt_consumer_task_msg_signal中会调用apr_queue_push将消息推入队列,并唤醒消费线程去消费。

————————————————
版权声明:本文为CSDN博主「罗自荣」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luozirong/article/details/78875325

freeswitch mrcp 源码分析--数据接收(上)相关推荐

  1. 【VUE】源码分析 - 数据劫持的基本原理

    tips:本系列博客的代码部分(示例等除外),均出自vue源码内容,版本为2.6.14.但是为了增加易读性,会对不相关内容做选择性省略.如果大家想了解完整的源码,建议自行从官方下载.https://g ...

  2. 基于TCP网络通信的自动升级程序源码分析-客户端接收文件

    升级程序客户端接收文件 /// <summary>/// 文件数据缓存 索引是 ConnectionInfo对象 数据包的顺序号 值是数据/// </summary>Dicti ...

  3. HBase源码分析之HRegion上compact流程分析(三)

    在<HBase源码分析之HRegion上compact流程分析(二)>一文中,我们没有讲解真正执行合并的CompactionContext的compact()方法.现在我们来分析下它的具体 ...

  4. Nginx源码分析--数据对齐posix_memalign和memalign函数

    posix_memalign函数() /*  * 背景:  *      1)POSIX 1003.1d  *      2)POSIX 标明了通过malloc( ), calloc( ), 和 re ...

  5. 风讯dotNETCMS源码分析—数据存取篇

    前几天突然对CMS感兴趣,就去下载了风讯dotNETCMS源码.当前版本是dotnetcms1.0 sp5免费版,风讯的官方主页上可以下载. 用Visual Studio 2008打开后,初步分析了它 ...

  6. 若依前后端分离版源码分析-前端头像上传后传递到后台以及在服务器上存储和数据库存储设计

    场景 使用若依前后端分离版本时,分析其头像上传机制. 可作为续参考学习. 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获 ...

  7. android+小米文件管理器源码,[MediaStore]小米文件管理器android版源码分析——数据来源...

    打开小米的文件管理器,我们很快会看到如下图所示的界面: 其中,会把各种文件分类显示.并且显示出每种文件的个数. 这是怎么做到的呢?当然不是每次启动都查询sdcard和应用程序data目录文件啦,那样实 ...

  8. freeSWITCH detect_speech源码分析

    前段时间用detect_speech配合阿里的引擎做了些ASR的测试.涉及到一点源码的改动.这里记录detect_speech的源码.有助于理解FS的ASR实现. 这里的源码基于V1.8.7描述. d ...

  9. gre tunnel源码分析之接收流程

    GRE(Generic Routing Encapsulation,通用路由封装)协议是对某些网络层协议(如IP 和IPX)的数据报文进行封装,使这些被封装的数据报文能够在另一个网络层协议(如IP)中 ...

  10. galler3d的源码分析——数据来源

    我们这里主要讲本地sd卡的数据,pisaca看情况后续再作分析. 数据操作设计的类包括:CacheService,MediaFeed,LocalDataSource,DiskCache,MediaIt ...

最新文章

  1. BZOJ1747 [Usaco2005 open]Expedition 探险
  2. 各类木材强度_木材的力学性能
  3. MySQL设置某一字段默认为0,但是插入数据化却显示为null
  4. ServletContextListener在Springboot中的使用
  5. NAT模式下虚拟机与主机网络关系配置
  6. HTML5 Canvas的基本用法
  7. python相机拍照显示_从solvePnP获取摄影机姿势
  8. 菜鸟启动“快递包装换鸡蛋”活动 史上最低碳的一届“双11”来了
  9. wamp无法访问php,wamp无法访问phpmyadmin怎么办
  10. hibernate文档
  11. L298电机驱动原理图+PCB
  12. win10 任务栏 网络 图标 消失 空白 network location awareness 错误1068
  13. QDir中mkdir和mkpath的区别
  14. 台式计算机如何安装摄像头,台式机怎样安装摄像头
  15. 7-5 jmu-Java-03面向对象基础-05-覆盖 (20 分)
  16. Type string trivially inferred from a string literal, remove type annotation.eslint@typescript-eslin
  17. 记录FinalShell退格键
  18. python 删除文件夹下面的所有文件python删除文件夹下面的所有文件夹及子文件
  19. unity3dwebgl building之后没有反应_晚会是在考验明星临场反应吗?王源开场无伴奏阿云嘎差点原地跳舞...
  20. java 判断文件是否存在

热门文章

  1. 数据分析神经网络模型图,神经网络模型数据处理
  2. [Android系统原理及开发要点详解
  3. Android debug时一直处于waiting for debugger解决办法
  4. 王者荣耀服务器微信怎么和电脑,[技术贴]微信账号与游戏账号独立的终极版教程...
  5. 重积分定理与计算总结
  6. 【改变键盘上方向键蹩脚的位置】通过autohotkey脚本实现键盘按键重映射【便利码代码】--以上下左右键映射为capslock与hjkl组合的按键 【附源码】
  7. 自动化测试八宗罪- 读Test Automation Snake Oil的一点翻译和感想
  8. javascript中onclick(this)用法和onclick(this.value)用法介绍
  9. 【阿里云服务器】ECS云服务器新手上路
  10. 迅捷PDF转换成word转换器