栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

srs源码分析4-客户端的连接

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

srs源码分析4-客户端的连接

本文分析的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()返回。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/292111.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号