博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nginx-rtmp-module 执行流程
阅读量:7075 次
发布时间:2019-06-28

本文共 8417 字,大约阅读时间需要 28 分钟。

hot3.png

nginx-rtmp-module 执行流程

 

统计模块数量

nginx.c中main()函数

ngx_max_module = 0;    for (i = 0; ngx_modules[i]; i++) {        ngx_modules[i]->index = ngx_max_module++;    }

上述代码在nginx.c的main函数中,其作用为:

  1. 统计系统中到底有多少个模块,记录在全局变量ngx_max_module中。
  2. 将每个模块在ngx_modules数组中的序号,记录在模块的index变量中。

在ngx_init_cycle函数执行每个模块ngx_modules[i]->ctx中的create_conf函数

for (i = 0; ngx_modules[i]; i++) {        if (ngx_modules[i]->type != NGX_CORE_MODULE) {            continue;        }        module = ngx_modules[i]->ctx;        if (module->create_conf) {            rv = module->create_conf(cycle);            if (rv == NULL) {                ngx_destroy_pool(pool);                return NULL;            }            cycle->conf_ctx[ngx_modules[i]->index] = rv;        }    }

以上代码对所有的ngx_core_module_t类型的模块,调用其ctx成员中的create_conf函数。

在ngx_init_cycle函数执行ngx_conf_param(&conf)和ngx_conf_parse(&conf, &cycle->conf_file)

 

ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)调用函数ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)。

在函数ngx_conf_handler中调用ngx_command_t 中的set()函数,即cmd->set(cf, cmd, conf);

对于模块ngx_rtmp_module,set函数对应ngx_rtmp_block

函数ngx_rtmp_block统计NGX_RTMP_MODULE数量

ngx_rtmp_max_module = 0;    for (m = 0; ngx_modules[m]; m++) {        if (ngx_modules[m]->type != NGX_RTMP_MODULE) {            continue;        }        ngx_modules[m]->ctx_index = ngx_rtmp_max_module++;    }

上面的代码主要做了两件事情:

  1. 遍历所有的ngx_rtmp_module_t类型的模块,统计这种模块的个数,存在变量ngx_rtmp_max_module中。
  2. 初始化每个ngx_rtmp_module_t类型的模块的ctx_index变量,该值的涵义是每个ngx_rtmp_module_t模块在所有该类模块中的序号。

函数ngx_rtmp_block调用ngx_rtmp_module_t create_main_conf、create_srv_conf和create_loc_conf函数

for (m = 0; ngx_modules[m]; m++) {        if (ngx_modules[m]->type != NGX_RTMP_MODULE) {            continue;        }        module = ngx_modules[m]->ctx;        mi = ngx_modules[m]->ctx_index;        if (module->create_main_conf) {            ctx->main_conf[mi] = module->create_main_conf(cf);            if (ctx->main_conf[mi] == NULL) {                return NGX_CONF_ERROR;            }        }        if (module->create_srv_conf) {            ctx->srv_conf[mi] = module->create_srv_conf(cf);            if (ctx->srv_conf[mi] == NULL) {                return NGX_CONF_ERROR;            }        }        if (module->create_app_conf) {            ctx->app_conf[mi] = module->create_app_conf(cf);            if (ctx->app_conf[mi] == NULL) {                return NGX_CONF_ERROR;            }        }

ngx_rtmp_conf_ctx_t中的指针数组main_conf,srv_conf和app_conf被赋值。

函数ngx_rtmp_block调用ngx_rtmp_module_t preconfiguration函数

for (m = 0; ngx_modules[m]; m++) {        if (ngx_modules[m]->type != NGX_RTMP_MODULE) {            continue;        }        module = ngx_modules[m]->ctx;        if (module->preconfiguration) {            if (module->preconfiguration(cf) != NGX_OK) {                return NGX_CONF_ERROR;            }        }    }

函数ngx_rtmp_block解析rtmp配置

/* parse inside the rtmp{} block */    cf->module_type = NGX_RTMP_MODULE;    cf->cmd_type = NGX_RTMP_MAIN_CONF;    rv = ngx_conf_parse(cf, NULL);    if (rv != NGX_CONF_OK) {        *cf = pcf;        return rv;    }

函数ngx_rtmp_block调用ngx_rtmp_module_t init_main_conf,merge_srv_conf和merge_app_conf函数

/* init rtmp{} main_conf's, merge the server{}s' srv_conf's */    cmcf = ctx->main_conf[ngx_rtmp_core_module.ctx_index];    cscfp = cmcf->servers.elts;    for (m = 0; ngx_modules[m]; m++) {        if (ngx_modules[m]->type != NGX_RTMP_MODULE) {            continue;        }        module = ngx_modules[m]->ctx;        mi = ngx_modules[m]->ctx_index;        /* init rtmp{} main_conf's */        cf->ctx = ctx;        if (module->init_main_conf) {            rv = module->init_main_conf(cf, ctx->main_conf[mi]);            if (rv != NGX_CONF_OK) {                *cf = pcf;                return rv;            }        }        for (s = 0; s < cmcf->servers.nelts; s++) {            /* merge the server{}s' srv_conf's */            cf->ctx = cscfp[s]->ctx;            if (module->merge_srv_conf) {                rv = module->merge_srv_conf(cf,                                            ctx->srv_conf[mi],                                            cscfp[s]->ctx->srv_conf[mi]);                if (rv != NGX_CONF_OK) {                    *cf = pcf;                    return rv;                }            }            if (module->merge_app_conf) {                /* merge the server{}'s app_conf */                /*ctx->app_conf = cscfp[s]->ctx->loc_conf;*/                rv = module->merge_app_conf(cf,                                            ctx->app_conf[mi],                                            cscfp[s]->ctx->app_conf[mi]);                if (rv != NGX_CONF_OK) {                    *cf = pcf;                    return rv;                }                /* merge the applications{}' app_conf's */                cscf = cscfp[s]->ctx->srv_conf[ngx_rtmp_core_module.ctx_index];                rv = ngx_rtmp_merge_applications(cf, &cscf->applications,                                            cscfp[s]->ctx->app_conf,                                            module, mi);                if (rv != NGX_CONF_OK) {                    *cf = pcf;                    return rv;                }            }        }    }

函数ngx_rtmp_block调用ngx_rtmp_module_t postconfiguration函数

for (m = 0; ngx_modules[m]; m++) {        if (ngx_modules[m]->type != NGX_RTMP_MODULE) {            continue;        }        module = ngx_modules[m]->ctx;        if (module->postconfiguration) {            if (module->postconfiguration(cf) != NGX_OK) {                return NGX_CONF_ERROR;            }        }    }

 

在ngx_init_cycle函数执行每个模块ngx_modules[i]->ctx中的init_conf函数

for (i = 0; ngx_modules[i]; i++) {        if (ngx_modules[i]->type != NGX_CORE_MODULE) {            continue;        }        module = ngx_modules[i]->ctx;        if (module->init_conf) {            if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])                == NGX_CONF_ERROR)            {                environ = senv;                ngx_destroy_cycle_pools(&conf);                return NULL;            }        }    }

以上代码对所有的ngx_core_module_t类型的模块,调用其ctx成员的init_conf钩子函数。

在ngx_init_cycle函数执行每个模块ngx_modules[i]中的init_module函数

for (i = 0; ngx_modules[i]; i++) {        if (ngx_modules[i]->init_module) {            if (ngx_modules[i]->init_module(cycle) != NGX_OK) {                /* fatal */                exit(1);            }        }    }

 

注释1 ngx_module_t:

struct ngx_module_s {    ngx_uint_t            ctx_index;    ngx_uint_t            index;    ngx_uint_t            spare0;    ngx_uint_t            spare1;    ngx_uint_t            spare2;    ngx_uint_t            spare3;    ngx_uint_t            version;    void                 *ctx;    ngx_command_t        *commands;    ngx_uint_t            type;    ngx_int_t           (*init_master)(ngx_log_t *log);    ngx_int_t           (*init_module)(ngx_cycle_t *cycle);    ngx_int_t           (*init_process)(ngx_cycle_t *cycle);    ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);    void                (*exit_thread)(ngx_cycle_t *cycle);    void                (*exit_process)(ngx_cycle_t *cycle);    void                (*exit_master)(ngx_cycle_t *cycle);    uintptr_t             spare_hook0;    uintptr_t             spare_hook1;    uintptr_t             spare_hook2;    uintptr_t             spare_hook3;    uintptr_t             spare_hook4;    uintptr_t             spare_hook5;    uintptr_t             spare_hook6;    uintptr_t             spare_hook7;};

注释2 ngx_core_module_t:

typedef struct {    ngx_str_t             name;    void               *(*create_conf)(ngx_cycle_t *cycle);    char               *(*init_conf)(ngx_cycle_t *cycle, void *conf);} ngx_core_module_t;

注释3 ngx_rtmp_module_t:

typedef struct {    ngx_int_t             (*preconfiguration)(ngx_conf_t *cf);    ngx_int_t             (*postconfiguration)(ngx_conf_t *cf);    void                 *(*create_main_conf)(ngx_conf_t *cf);    char                 *(*init_main_conf)(ngx_conf_t *cf, void *conf);    void                 *(*create_srv_conf)(ngx_conf_t *cf);    char                 *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,                                    void *conf);    void                 *(*create_app_conf)(ngx_conf_t *cf);    char                 *(*merge_app_conf)(ngx_conf_t *cf, void *prev,                                    void *conf);} ngx_rtmp_module_t;

 

转载于:https://my.oschina.net/u/2326611/blog/848920

你可能感兴趣的文章
极简反传(BP)神经网络
查看>>
阿里巴巴面试题集合
查看>>
Android视频直播解决方案(rstp、udp)
查看>>
HTML5实战与剖析之媒体元素(6、视频实例)
查看>>
NTFS For Mac 的特点有哪些
查看>>
新技能,利用Reflector来修改dll引用
查看>>
Java编程的逻辑 (1) - 数据和变量
查看>>
我的屌丝giser成长记-研一篇(下)
查看>>
raft 分布式协议 -- mongodb
查看>>
[TypeScript] Using Lodash in TypeScript with Typings and SystemJS
查看>>
ASP.Net MVC开发基础学习笔记(1):走向MVC模式
查看>>
虚函数可不可以是内联函数
查看>>
据说看完这21个故事的人,30岁前都成了亿万富翁
查看>>
HDOJ-4505 小Q系列故事——电梯里的爱情
查看>>
【转】Navigation Drawer(导航抽屉)
查看>>
Linux Shell常用技巧(十)
查看>>
【从零之三(更)】自定义类中调用讯飞语音包错误解决办法
查看>>
【源代码】LinkedHashMap源代码剖析
查看>>
Android InputStream转Bitmap
查看>>
记录水电系统开发的心理【1】
查看>>