SRS之SrsServer::cycle()

1. SrsServer 相关类定义

1.1 SrsServer 类定义

/**
 * SRS RTMP server, initialize and listen,
 * start connection service thread, destroy client.
 */
class SrsServer : virtual public ISrsReloadHandler 
    , virtual public ISrsSourceHandler
    , virtual public IConnectionManager
{
private:
#ifdef SRS_AUTO_HTTP_API
    // TODO: FIXME: rename to http_api
    SrsHttpServeMux* http_api_mux;
#endif
#ifdef SRS_AUTO_HTTP_SERVER
    SrsHttpServer* http_server;
#endif
#ifdef SRS_AUTO_HTTP_CORE
    SrsHttpHeartbeat* http_heartbeat;
#endif
#ifdef SRS_AUTO_INGEST
    SrsIngester* ingester;
#endif
private:
    /**
     * the pid file fd, lock the file write when server is running.
     * @remark the init.d script should cleanup the pid file, when stop service,
     *         for the server never delete the file; when system startup, the pid
     *         in pid file maybe valid but the process is not SRS, the init.d script 
     *         will never start server.
     */
    int pid_fd;
    /**
     * all connections, connection manager
     */
    std::vector<SrsConnection*> conns;
    /**
     * all listeners, listener manager.
     */
    std::vector<SrsListener*> listeners;
    /**
     * signal manager which convert signal to io message.
     */
    SrsSignalManager* signal_manager;
    /**
     * handle in server cycle.
     */
    ISrsServerCycle* handler;
    /**
     * user send the signal, convert to variable.
     */
    bool signal_reload;
    bool signal_gmc_stop;
    bool signal_gracefully_quit;
    /* parent pid for asprocess. */
    int ppid;
public:
    SrsServer();
    virtual ~SrsServer();
private:
    /**
     * the destroy is for gmc to analysis the memory leak,
     * if not destroy global/static data, the gmc will will warning memory leak.
     * in service, server never destroy, directly exit when restart.
     */
    virtual void destroy();
    /**
     * when SIGTERM, SRS should do cleanup, for example,
     * to stop all ingesters, cleanup HLS and dvr.
     */
    virtual void dispose();
// server startup workflow, @see run_master()
public:
    /**
     * initialize server with callback handler.
     * @remark user must free the cycle handler.
     */
    virtual int initialize(ISrsServerCycle* cycle_handler);
    virtual int initialize_st();
    virtual int initialize_signal();
    virtual int acquire_pid_file();
    virtual int listen();
    virtual int register_signal();
    virtual int http_handle();
    virtual int ingest();
    virtual int cycle();
// IConnectionManager
public:
    /**
     * callback for connection to remove itself.
     * when connection thread cycle terminatedk, callback this to delete connection.
     * @see SrsConnection.on_thread_stop().
     */
    virtual void remove(SrsConnection* conn);
// server utilities.
public:
    /**
     * callback for signal manager got a signal.
     * the signal manager convert signal to io message,
     * whatever, we will got the signo like the orignal signal(int signo) handler.
     * @remark, directly exit for SIGTERM.
     * @remark, do reload for SIGNAL_RELOAD.
     * @remark, for SIGINT and SIGUSR2:
     *       no gmc, directly exit.
     *       for gmc, set the variable signal_gmc_stop, the cycle will return 
     *       and cleanup for gmc.
     */
    virtual void on_signal(int signo);
private:
    /**
     * the server thread main cycle,
     * update the global static data, for instance, the current time,
     * the cpu/mem/network statistic.
     */
    virtual int do_cycle();
    /**
     * listen at specified protocol.
     */
    virtual int listen_rtmp();
    virtual int listen_http_api();
    virtual int listen_http_stream();
    virtual int listen_stream_caster();
    /**
     * close the listeners for specified type,
     * remove the listen object from manager.
     */
    virtual void close_listeners(SrsListenerType type);
    /**
     * resample the server kbs.
     */
    virtual void resample_kbps();
// internal only
public:
    /**
     * when listener got a fd, notice server to accept it.
     * @param type, the client type, used to create concreate connection,
     *        for instance RTMP connection to server client.
     * @param client_stfd, the client fd in st boxed, the underlayer fd.
     */
    virtual int accept_client(SrsListenerType type, st_netfd_t client_stfd);
// interface ISrsReloadHandler.
public:
    virtual int on_reload_listen();
    virtual int on_reload_pid();
    virtual int on_reload_vhost_added(std::string vhost);
    virtual int on_reload_vhost_removed(std::string vhost);
    virtual int on_reload_http_api_enabled();
    virtual int on_reload_http_api_disabled();
    virtual int on_reload_http_stream_enabled();
    virtual int on_reload_http_stream_disabled();
    virtual int on_reload_http_stream_updated();
// interface ISrsSourceHandler
public:
    virtual int on_publish(SrsSource* s, SrsRequest* r);
    virtual void on_unpublish(SrsSource* s, SrsRequest* r);
};

1.2 ISrsReloadHandler 类定义

/**
 * the handler for config reload.
 * when reload callback, the config is updated yet.
 * 
 * features not support reload, 
 * @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures
 */
class ISrsReloadHandler
{
public:
    ISrsReloadHandler();
    virtual ~ISrsReloadHandler();
public:
    virtual int on_reload_utc_time();
    virtual int on_reload_max_conns();
    virtual int on_reload_listen();
    virtual int on_reload_pid();
    virtual int on_reload_log_tank();
    virtual int on_reload_log_level();
    virtual int on_reload_log_file();
    virtual int on_reload_pithy_print();
    virtual int on_reload_http_api_enabled();
    virtual int on_reload_http_api_disabled();
    virtual int on_reload_http_stream_enabled();
    virtual int on_reload_http_stream_disabled();
    virtual int on_reload_http_stream_updated();
public:
    // TODO: FIXME: should rename to http_static
    virtual int on_reload_vhost_http_updated();
    virtual int on_reload_vhost_http_remux_updated(std::string vhost);
    virtual int on_reload_vhost_added(std::string vhost);
    virtual int on_reload_vhost_removed(std::string vhost);
    virtual int on_reload_vhost_atc(std::string vhost);
    virtual int on_reload_vhost_gop_cache(std::string vhost);
    virtual int on_reload_vhost_queue_length(std::string vhost);
    virtual int on_reload_vhost_time_jitter(std::string vhost);
    virtual int on_reload_vhost_mix_correct(std::string vhost);
    virtual int on_reload_vhost_forward(std::string vhost);
    virtual int on_reload_vhost_hls(std::string vhost);
    virtual int on_reload_vhost_hds(std::string vhost);
    virtual int on_reload_vhost_dvr(std::string vhost);
    virtual int on_reload_vhost_mr(std::string vhost);
    virtual int on_reload_vhost_mw(std::string vhost);
    virtual int on_reload_vhost_smi(std::string vhost);
    virtual int on_reload_vhost_tcp_nodelay(std::string vhost);
    virtual int on_reload_vhost_realtime(std::string vhost);
    virtual int on_reload_vhost_p1stpt(std::string vhost);
    virtual int on_reload_vhost_pnt(std::string vhost);
    virtual int on_reload_vhost_chunk_size(std::string vhost);
    virtual int on_reload_vhost_transcode(std::string vhost);
    virtual int on_reload_ingest_removed(std::string vhost, std::string ingest_id);
    virtual int on_reload_ingest_added(std::string vhost, std::string ingest_id);
    virtual int on_reload_ingest_updated(std::string vhost, std::string ingest_id);
    virtual int on_reload_user_info();
};

1.3 ISrsSourceHandler 类定义

/**
 * the handler to handle the event of srs source.
 * for example, the http flv streaming module handle the event and 
 * mount http when rtmp start publishing.
 */
class ISrsSourceHandler
{
public:
    ISrsSourceHandler();
    virtual ~ISrsSourceHandler();
public:
    /**
    * when stream start publish, mount stream.
    */
    virtual int on_publish(SrsSource* s, SrsRequest* r) = 0;
    /**
    * when stream stop publish, unmount stream.
    */
    virtual void on_unpublish(SrsSource* s, SrsRequest* r) = 0;
};

1.4 IConnectionManager

/**
 * the manager for connection.
 */
class IConnectionManager
{
public:
    IConnectionManager();
    virtual ~IConnectionManager();
public:
    /**
     * remove the specified connection.
     */
    virtual void remove(SrsConnection* c) = 0;
};

SrsServer 和 ISrsReloadHandler、ISrsSourceHandler 以及 IConnectionManager 之间的关系(继承)
在这里插入图片描述

2. int SrsServer::cycle

位于 srs_app_server.cpp:

int SrsServer::cycle()
{
    int ret = ERROR_SUCCESS;
    
    /* 开始进入 SRS 的主循环 */
    ret = do_cycle();
    
#ifdef SRS_AUTO_GPERF_MC
    destroy();
    
    // remark, for gmc, never invoke the exit().
    srs_warn("sleep a long time for system st-threads to cleanup.");
    st_usleep(3 * 1000 * 1000);
    srs_warn("system quit");
#else
    // normally quit with neccessary cleanup by dispost().
    srs_warn("main cycle terminated, system quit normally.");
    dispose();
    srs_trace("srs terminated");
    
    // for valgrind to detect.
    srs_freep(_srs_config);
    srs_freep(_srs_log);
    
    exit(0);
#endif

    return ret;
}

2.1 SrsServer::do_cycle

int SrsServer::do_cycle()
{
    int ret = ERROR_SUCCESS;
    
    // find the max loop
    int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES);

#ifdef SRS_AUTO_STAT
    max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_DISK_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES);
#endif
    
    // for asprocess.
    bool asprocess = _srs_config->get_asprocess();
    
    // the daemon thread, update the time cache
    while (true) {
        /* 这里 handler 初始化为 NULL,所以忽略 */
        if (handler && (ret = handler->on_cycle((int)conns.size())) != ERROR_SUCCESS) {
            srs_error("cycle handle failed. ret=%d", ret);
            return ret;
        }
        
        // the interval in config.
        int heartbeat_max_resolution = (int)(_srs_config->get_heartbeat_interval() \
                                       / SRS_SYS_CYCLE_INTERVAL);
        
        // dynamic fetch the max.
        int temp_max = max;
        temp_max = srs_max(temp_max, heartbeat_max_resolution);
        
        for (int i = 0; i < temp_max; i++) {
            /* 主线程进入休眠,调度其他线程运行,比如调度 conn 线程,接收
             * 客户端的连接 */
            st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
            
            // asprocess check.
            if (asprocess && ::getppid() != ppid) {
                srs_warn("asprocess ppid changed from %d to %d", ppid, ::getppid());
                return ret;
            }
            
            // gracefully quit for SIGINT or SIGTERM.
            if (signal_gracefully_quit) {
                srs_trace("cleanup for gracefully terminate");
                return ret;
            }
            
            // for gperf heap checker,
            // @see: research/gperftools/heap-checker/heap_checker.cc
            // if user interrupt the program, exit to check mem leak.
            // but, if gperf, use reload to ensure main return normally,
            // because directly exit will cause core-dump.
#ifdef SRS_AUTO_GPERF_MC
            if (signal_gmc_stop) {
                srs_warn("gmc got singal to stop server.");
                return ret;
            }
#endif      
            
            // do reload the config.
            if (signal_reload) {
                signal_reload = false;
                srs_info("get signal reload, to reload the config.");
                
                if ((ret = _srs_config->reload()) != ERROR_SUCCESS) {
                    srs_error("reload config failed. ret=%d", ret);
                    return ret;
                }
                srs_trace("reload config success.");
            }
            
            // notice the stream sources to cycle.
            if ((ret = SrsSource::cycle_all()) != ERROR_SUCCESS) {
                return ret;
            }
            
            // update the cache time
            if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) {
                srs_info("update current time cache.");
                srs_update_system_time_ms();
            }
            
#ifdef SRS_AUTO_STAT
            if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) {
                srs_info("update resource info, rss.");
                srs_update_system_rusage();
            }
            if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) {
                srs_info("update cpu info, cpu usage.");
                srs_update_proc_stat();
            }
            if ((i % SRS_SYS_DISK_STAT_RESOLUTION_TIMES) == 0) {
                srs_info("update disk info, disk iops.");
                srs_update_disk_stat();
            }
            if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) {
                srs_info("update memory info, usage/free.");
                srs_update_meminfo();
            }
            if ((i % SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES) == 0) {
                srs_info("update platform info, uptime/load.");
                srs_update_platform_info();
            }
            if ((i % SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES) == 0) {
                srs_info("update network devices info.");
                srs_update_network_devices();
            }
            if ((i % SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES) == 0) {
                srs_info("update network server kbps info.");
                resample_kbps();
            }
    #ifdef SRS_AUTO_HTTP_CORE
            if (_srs_config->get_heartbeat_enabled()) {
                if ((i % heartbeat_max_resolution) == 0) {
                    srs_info("do http heartbeat, for internal server to report.");
                    http_heartbeat->heartbeat();
                }
            }
    #endif
#endif
            
            srs_info("server main thread loop");
        }
    }
}

在该函数中,该主线程循环进行休眠,以便调度其他线程运行。

音视频流媒体高级开发:https://ke.qq.com/course/3202131?flowToken=1031864
音视频开发学习资料分享,有需要的可以自行添加学习交流群739729163 领取
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SRS(Simple Rtmp Server)的定位是运营级的互联网直播服务器集群,追求更好的概念完整性和最简单实现的代码。 • 运营级: 商业运营追求极高的稳定性,良好的系统对接,以及错误排查和处理机制。譬如日志文件格式,reload,系统HTTP接口,提供init.d脚本,转发,转码,边缘回多源站,都是根据CDN运营经验作为判断这些功能作为核心的依据。 • 互联网: 互联网最大的特征是变化,唯一不变的就是不断变化的客户要求,唯一不变的是基础结构的概念完整性和简洁性。互联网还意味着参与性,听取用户的需求和变更,持续改进和维护。 • 直播服务器: 直播和点播这两种截然不同的业务类型,导致架构和目标完全不一致,从运营的设备组,应对的挑战都完全不同。两种都支持只能说明没有重心,或者低估了代价。 • 集群: FMS(AMS)的集群还是很不错的,虽然在运营容错很差。SRS(Simple Rtmp Server)支持完善的直播集群,Vhost分为源站和边缘,容错支持多源站切换、测速、可追溯日志等。 • 概念完整性: 虽然代码甚至结构都在变化,但是结构的概念完整性是一直追求的目标。从SRS(Simple Rtmp Server)服务器,P2P,ARM监控产业,MIPS路由器,服务器监控管理,ARM智能手机,SRS(Simple Rtmp Server)的规模不再是一个服务器而已。 • 简单实现: 对于过于复杂的实现,宁可不加入这个功能,也不牺牲前面提到的要求。对于已经实现的功能的代码,总会在一个版本release前给予充分的时间来找出最简答案。不求最高性能,最优雅,最牛逼,但求最简单易懂。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值