本文分析的srs版本是0.6.0
srs源码分析1-搭建环境
srs源码分析2-浅析state_threads
srs源码分析3-srs的启动
srs源码分析4-客户端的连接
srs源码分析5-handshake
srs源码分析6-connect
以下正在写作中。。。
srs源码分析7-create stream
srs源码分析8-推流-publish
srs源码分析9-推流-unpublish
srs源码分析10-拉流-play
srs源码分析11-拉流-pause
srs源码分析12-转发-forward
void SrsListener::listen_cycle()
{
...
while (loop) {
...
st_netfd_t client_stfd = st_accept(stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT);
...
if ((ret = server->accept_client(type, client_stfd)) != ERROR_SUCCESS) {
srs_warn("accept client error. ret=%d", ret);
continue;
}
}
}
srs启动后创建的listen协程用于监听客户端的连接,当有客户端连接srs时,listen协程会从st_accept函数返回。
int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
{
int ret = ERROR_SUCCESS;
SrsConnection* conn = NULL;
if (type == SrsListenerStream) {
conn = new SrsClient(this, client_stfd);
} else {
// handler others
}
srs_assert(conn);
conns.push_back(conn);
srs_verbose("add conn from port %d to vector. conns=%d", port, (int)conns.size());
if ((ret = conn->start()) != ERROR_SUCCESS) {
return ret;
}
srs_verbose("conn start finished. ret=%d", ret);
return ret;
}
SrsServer会为客户端创建一个连接句柄SrsClient,之后该客户端的所有请求都由SrsClient对象处理。
int SrsConnection::start()
{
int ret = ERROR_SUCCESS;
if (st_thread_create(cycle_thread, this, 0, 0) == NULL) {
ret = ERROR_ST_CREATE_CYCLE_THREAD;
srs_error("st_thread_create conn cycle thread error. ret=%d", ret);
return ret;
}
srs_verbose("create st conn cycle thread success.");
return ret;
}
srs会为每个连接的客户端创建一个client协程,之后该客户端的所有请求都由该client协程处理。
void* SrsConnection::cycle_thread(void* arg)
{
SrsConnection* conn = (SrsConnection*)arg;
srs_assert(conn != NULL);
conn->cycle();
return NULL;
}
void SrsConnection::cycle()
{
...
ret = do_cycle();
...
server->remove(this);
}
cycle_thread函数是协程的入口函数,注意此函数是类的静态成员函数。
SrsConnection是SrsClient的父类,通过父类的指针调用虚函数会发生多态。do_cycle()等价于this->do_cycle()所以do_cycle()实际调用的是SrsClient中的do_cycle()函数。
int SrsClient::do_cycle()
{
int ret = ERROR_SUCCESS;
if ((ret = get_peer_ip()) != ERROR_SUCCESS) {
srs_error("get peer ip failed. ret=%d", ret);
return ret;
}
srs_trace("get peer ip success. ip=%s, send_to=%"PRId64", recv_to=%"PRId64"", ip, SRS_SEND_TIMEOUT_US, SRS_RECV_TIMEOUT_US);
rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US);
rtmp->set_send_timeout(SRS_SEND_TIMEOUT_US);
if ((ret = rtmp->handshake()) != ERROR_SUCCESS) {
srs_error("rtmp handshake failed. ret=%d", ret);
return ret;
}
srs_verbose("rtmp handshake success");
...
}
客户端连接成功后,srs开始处理握手信息。
SrsClient::do_cycle()
-->SrsRtmp::handshake()
-->SrsSimpleHandshake::handshake_with_client()
-->SrsSocket::read_fully()
client协程创建后,获取CPU的执行权后,会通过上面的函数调用,最后"阻塞"在SrsSocket::read_fully()上等待客户端发送握手报文,同时让出CPU执行权,当客户端发送握手报文后,client协程会从SrsSocket::read_fully()返回。



