next_xxx方法管理
在nginx的rtmp模块的各个子模块中,我们会看见有很多的next_xxx方法的回调方法,例如next_play或者next_publish,他们调用的是什么方法?又是怎样赋值的呢?
我们使用next_publish回调方法进行说明:
首先,我们看一下该函数的定义,我们可以在各个会使用他的模块中都看到一个static的定义的全局回调方法:static ngx_rtmp_publish_pt next_publish;
在C语言中,static字段定义的数据存储在静态数据区,他的访问权限为定义他的方法或者文件(文件的全局变量)中;
按照C语言的规范next_publish方法为文件的全局静态变量,所以他的访问只能在定义它的文件中使用;我们查看他的赋值,会发现,在每个模块的xxx_postconfiguration方法中会给他赋值:
1 next_publish = ngx_rtmp_publish; 2 ngx_rtmp_publish = ngx_rtmp_log_publish;
在上面的第1行中,我们可以看到我们将ngx_rtmp_publish赋值给了next_publish回调,而查看ngx_rtmp_publish的定义,可以发现他也是一个函数的指针,类型和next_publish一样,不同的是,ngx_rtmp_publish是全局的,所以在rtmp-module的各个文件中都能够访问到他;
上面的第2行代码显示,我们将方法ngx_rtmp_log_publish赋值给了ngx_rtmp_publish,所以当下一个访问ngx_rtmp_publish函数指针的地方,其实访问的是ngx_rtmp_log_publish方法;
> nginx的next_xxx函数调用链就是利用这种文件内的static函数指针和一个全局的函数指针形成的;由于static的函数指针是在各个子模块的xxx_postconfiguration方法中调用,而xxx_postconfiguration是在nginx初始化时,模块加载之后,立即执行的,并且各个模块的xxx_postconfiguration方法是在同一个进程中同步调用的,所以在加载完前一个模块的时候,我们给全局函数指针ngx_rtmp_publish赋值了,在在该该模块的时候,当我们使用next_publish = ngx_rtmp_publish
给next_publish赋值的时候,就是让next_publish指向前一个xxx_postconfiguration方法中,给ngx_rtmp_publish赋值的函数;
这样的话,形成一个逻辑上的链表,而上面的赋值的过程,相当于给链表的头部添加一个节点;并且当我们需要访问下一个模块的方法的时候,不需要取进行查找。
需要注意的是,链表的生成和rtmp模块中的子模块的加载顺序是相关的,这个的话,就需要取查看编译时,生成的nginx_module.c文件中**ngx_module_t *ngx_modules[];**数组中定义的顺序
ngx_module_t *ngx_modules[] = { &ngx_core_module, &ngx_errlog_module, &ngx_conf_module, &ngx_rtmp_module, &ngx_rtmp_core_module, &ngx_rtmp_cmd_module, &ngx_rtmp_codec_module, &ngx_rtmp_access_module, &ngx_rtmp_record_module, &ngx_rtmp_live_module, &ngx_rtmp_play_module, &ngx_rtmp_flv_module, &ngx_rtmp_mp4_module, &ngx_rtmp_netcall_module, &ngx_rtmp_relay_module, &ngx_rtmp_exec_module, &ngx_rtmp_auto_push_module, &ngx_rtmp_auto_push_index_module, &ngx_rtmp_notify_module, &ngx_rtmp_log_module, &ngx_rtmp_limit_module, &ngx_rtmp_hls_module, &ngx_rtmp_dash_module, &ngx_openssl_module, &ngx_regex_module, &ngx_events_module, &ngx_event_core_module, &ngx_epoll_module, &ngx_http_module, &ngx_http_core_module, &ngx_http_log_module, &ngx_http_upstream_module, &ngx_http_static_module, &ngx_http_autoindex_module, &ngx_http_index_module, &ngx_http_mirror_module, &ngx_http_try_files_module, &ngx_http_auth_basic_module, &ngx_http_access_module, &ngx_http_limit_conn_module, &ngx_http_limit_req_module, &ngx_http_geo_module, &ngx_http_map_module, &ngx_http_split_clients_module, &ngx_http_referer_module, &ngx_http_rewrite_module, &ngx_http_proxy_module, &ngx_http_fastcgi_module, &ngx_http_uwsgi_module, &ngx_http_scgi_module, &ngx_http_memcached_module, &ngx_http_empty_gif_module, &ngx_http_browser_module, &ngx_http_upstream_hash_module, &ngx_http_upstream_ip_hash_module, &ngx_http_upstream_least_conn_module, &ngx_http_upstream_random_module, &ngx_http_upstream_keepalive_module, &ngx_http_upstream_zone_module, &ngx_rtmp_stat_module, &ngx_rtmp_control_module, &ngx_http_write_filter_module, &ngx_http_header_filter_module, &ngx_http_chunked_filter_module, &ngx_http_range_header_filter_module, &ngx_http_gzip_filter_module, &ngx_http_postpone_filter_module, &ngx_http_ssi_filter_module, &ngx_http_charset_filter_module, &ngx_http_userid_filter_module, &ngx_http_headers_filter_module, &ngx_http_copy_filter_module, &ngx_http_range_body_filter_module, &ngx_http_not_modified_filter_module, NULL };
从上面带有rtmp字段命名的是我们的rtmp模块的,从上面的模块加载顺序,我们可以得出整个next_xxx方法的调用关系文件为:
&ngx_rtmp_control_module,
&ngx_rtmp_stat_module,
&ngx_rtmp_dash_module,
&ngx_rtmp_hls_module,
&ngx_rtmp_limit_module,
&ngx_rtmp_log_module,
&ngx_rtmp_notify_module,
&ngx_rtmp_auto_push_index_module,
&ngx_rtmp_auto_push_module,
&ngx_rtmp_exec_module,
&ngx_rtmp_relay_module,
&ngx_rtmp_netcall_module,
&ngx_rtmp_mp4_module,
&ngx_rtmp_flv_module,
&ngx_rtmp_play_module,
&ngx_rtmp_live_module,
&ngx_rtmp_record_module,
&ngx_rtmp_access_module,
&ngx_rtmp_codec_module,
&ngx_rtmp_cmd_module,
&ngx_rtmp_core_module,
ngx_rtmp_module,