美文网首页
srs启动监听过程

srs启动监听过程

作者: hijiang | 来源:发表于2019-06-10 23:39 被阅读0次

srs在启动初始化,配置等完成后,开始执行socket监听:

int run_master()
{
    int ret = ERROR_SUCCESS;
    ...
    if ((ret = _srs_server->listen()) != ERROR_SUCCESS) {
        return ret;
    }
    ...
    
    return 0;
}

int SrsServer::listen()
{
    int ret = ERROR_SUCCESS;
    
    if ((ret = listen_rtmp()) != ERROR_SUCCESS) {
        return ret;
    }
    
    if ((ret = listen_http_api()) != ERROR_SUCCESS) {
        return ret;
    }
    
    if ((ret = listen_http_stream()) != ERROR_SUCCESS) {
        return ret;
    }
    
    if ((ret = listen_stream_caster()) != ERROR_SUCCESS) {
        return ret;
    }
    
    return ret;
}

我们只关注listen_rtmp即可:

int SrsServer::listen_rtmp()
{
    int ret = ERROR_SUCCESS;
    
    // stream service port.
    std::vector<std::string> ip_ports = _srs_config->get_listens();
    srs_assert((int)ip_ports.size() > 0);
    
    close_listeners(SrsListenerRtmpStream);
    
    for (int i = 0; i < (int)ip_ports.size(); i++) {
        SrsListener* listener = new SrsStreamListener(this, SrsListenerRtmpStream);
        listeners.push_back(listener);
        
        std::string ip;
        int port;
        srs_parse_endpoint(ip_ports[i], ip, port);
        
        if ((ret = listener->listen(ip, port)) != ERROR_SUCCESS) {
            srs_error("RTMP stream listen at %s:%d failed. ret=%d", ip.c_str(), port, ret);
            return ret;
        }
    }
    
    return ret;
}

这里根据配置,启动了多个监听器监听多个端口,但我们一般上就用一个1935端口。
继续看:

int SrsStreamListener::listen(string i, int p)
{
    int ret = ERROR_SUCCESS;
    
    ip = i;
    port = p;

    srs_freep(listener);
    listener = new SrsTcpListener(this, ip, port);

    if ((ret = listener->listen()) != ERROR_SUCCESS) {
        srs_error("tcp listen failed. ret=%d", ret);
        return ret;
    }
    
    srs_info("listen thread current_cid=%d, "
        "listen at port=%d, type=%d, fd=%d started success, ep=%s:%d",
        _srs_context->get_id(), p, type, listener->fd(), i.c_str(), p);

    srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd());

    return ret;
}

这里会启动一个SrsTcpListener来监听,而SrsTcpListener内部会创建并启动一个SrsReusableThread:

SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, string i, int p)
{
    handler = h;
    ip = i;
    port = p;

    _fd = -1;
    _stfd = NULL;

    pthread = new SrsReusableThread("tcp", this);
}

而SrsReusableThread内部会创建一个SrsThread,这个是最近的协程封装,使用它时,我们需要给它传递一个具体的handler对象,使得这个协程与具体的处理解耦,协程内部会循环调用handler的cycle()处理,而这里的cycle就是:

int SrsTcpListener::cycle()
{
    int ret = ERROR_SUCCESS;
    
    st_netfd_t client_stfd = st_accept(_stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT);
    
    if(client_stfd == NULL){
        // ignore error.
        if (errno != EINTR) {
            srs_error("ignore accept thread stoppped for accept client error");
        }
        return ret;
    }
    srs_verbose("get a client. fd=%d", st_netfd_fileno(client_stfd));
    
    if ((ret = handler->on_tcp_client(client_stfd)) != ERROR_SUCCESS) {
        srs_warn("accept client error. ret=%d", ret);
        return ret;
    }
    
    return ret;
}

之后,当收到请求后,调用on_tcp_client处理,这个又通过SrsStreamListener::on_tcp_client-->SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd),最终传递给SrsServer处理
而SrsServer将其封装成一个SrsRtmpConn对象,调用其start方法,执行rtmp连接的处理流程,连接处理流程包括了信令处理及音视频处理两部分,信令处理在后面一篇文章再详说。

相关文章

网友评论

      本文标题:srs启动监听过程

      本文链接:https://www.haomeiwen.com/subject/joexfctx.html