• SRS流媒体服务器:RTMP推流、拉流创建连接


    目录

    1. 识别客户端,然后获取或者创建SrsLiveSource
    2. 启动推流
    3. 启动拉流

    1. RTMP推流、拉流创建连接

    1.1RTMP推流和拉流创建连接对象的⽅式都是创建了SrsRtmpConn,见上面SrsServer::fd_to_resource函数。

    1.2每个SrsRtmpConn都绑定⼀个SrsCoroutine,具体的业务处理在SrsCoroutine的循环进⾏,对于RTMP⽽⾔最终的循环为SrsRtmpConn::cycle函数。

    1.3而SrsRtmpConn::cycle函数最终会调用SrsRtmpConn::do_cycle函数。

    1. srs_error_t SrsRtmpConn::do_cycle()
    2. {
    3. srs_error_t err = srs_success;
    4. srs_trace("RTMP client ip=%s:%d, fd=%d", ip.c_str(), port, srs_netfd_fileno(stfd));
    5. rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TIMEOUT);
    6. rtmp->set_send_timeout(SRS_CONSTS_RTMP_TIMEOUT);
    7. if ((err = rtmp->handshake()) != srs_success) { //RTMP握手逻辑
    8. return srs_error_wrap(err, "rtmp handshake");
    9. }
    10. uint32_t rip = rtmp->proxy_real_ip();
    11. if (rip > 0) {
    12. srs_trace("RTMP proxy real client ip=%d.%d.%d.%d",
    13. uint8_t(rip>>24), uint8_t(rip>>16), uint8_t(rip>>8), uint8_t(rip));
    14. }
    15. SrsRequest* req = info->req;
    16. if ((err = rtmp->connect_app(req)) != srs_success) { //接收connect请求
    17. return srs_error_wrap(err, "rtmp connect tcUrl");
    18. }
    19. // set client ip to request.
    20. req->ip = ip;
    21. srs_trace("connect app, tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%d, app=%s, args=%s",
    22. req->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(),
    23. req->schema.c_str(), req->vhost.c_str(), req->port,
    24. req->app.c_str(), (req->args? "(obj)":"null"));
    25. ...
    26. if ((err = service_cycle()) != srs_success) {
    27. err = srs_error_wrap(err, "service cycle");
    28. }
    29. srs_error_t r0 = srs_success;
    30. if ((r0 = on_disconnect()) != srs_success) {
    31. err = srs_error_wrap(err, "on disconnect %s", srs_error_desc(r0).c_str());
    32. srs_freep(r0);
    33. }
    34. // If client is redirect to other servers, we already logged the event.
    35. if (srs_error_code(err) == ERROR_CONTROL_REDIRECT) {
    36. srs_error_reset(err);
    37. }
    38. return err;
    39. }

    1.4SrsRtmpConn::cycle函数主要是进行RTMP握手,接收connect请求,判断为有效连接后调用SrsRtmpConn::service_cycle函数。

    1.4.1todo:后续会写一篇具体RTMP握手过程,命令控制消息和协议控制消息交互逻辑文章。

    1. srs_error_t SrsRtmpConn::service_cycle()
    2. {
    3. srs_error_t err = srs_success;
    4. SrsRequest* req = info->req;
    5. int out_ack_size = _srs_config->get_out_ack_size(req->vhost);
    6. if (out_ack_size && (err = rtmp->set_window_ack_size(out_ack_size)) != srs_success) {
    7. return srs_error_wrap(err, "rtmp: set out window ack size");
    8. }
    9. int in_ack_size = _srs_config->get_in_ack_size(req->vhost);
    10. if (in_ack_size && (err = rtmp->set_in_window_ack_size(in_ack_size)) != srs_success) {
    11. return srs_error_wrap(err, "rtmp: set in window ack size");
    12. }
    13. if ((err = rtmp->set_peer_bandwidth((int)(2.5 * 1000 * 1000), 2)) != srs_success) {
    14. return srs_error_wrap(err, "rtmp: set peer bandwidth");
    15. }
    16. // get the ip which client connected.
    17. std::string local_ip = srs_get_local_ip(srs_netfd_fileno(stfd));
    18. // do bandwidth test if connect to the vhost which is for bandwidth check.
    19. if (_srs_config->get_bw_check_enabled(req->vhost)) {
    20. if ((err = bandwidth->bandwidth_check(rtmp, skt, req, local_ip)) != srs_success) {
    21. return srs_error_wrap(err, "rtmp: bandwidth check");
    22. }
    23. return err;
    24. }
    25. // set chunk size to larger.
    26. // set the chunk size before any larger response greater than 128,
    27. // to make OBS happy, @see https://github.com/ossrs/srs/issues/454
    28. int chunk_size = _srs_config->get_chunk_size(req->vhost);
    29. if ((err = rtmp->set_chunk_size(chunk_size)) != srs_success) {
    30. return srs_error_wrap(err, "rtmp: set chunk size %d", chunk_size);
    31. }
    32. // response the client connect ok. 响应客户端connect请求
    33. if ((err = rtmp->response_connect_app(req, local_ip.c_str())) != srs_success) {
    34. return srs_error_wrap(err, "rtmp: response connect app");
    35. }
    36. if ((err = rtmp->on_bw_done()) != srs_success) {
    37. return srs_error_wrap(err, "rtmp: on bw down");
    38. }
    39. while (true) {
    40. if ((err = trd->pull()) != srs_success) {
    41. return srs_error_wrap(err, "rtmp: thread quit");
    42. }
    43. err = stream_service_cycle();
    44. // stream service must terminated with error, never success.
    45. // when terminated with success, it's user required to stop.
    46. // TODO: FIXME: Support RTMP client timeout, https://github.com/ossrs/srs/issues/1134
    47. if (err == srs_success) {
    48. continue;
    49. }
    50. ...
    51. // for other system control message, fata
  • 相关阅读:
    Elastic 线下 Meetup 将于 2024 年 7 月 27 号在深圳举办
    VulnHub narak
    HDLBits-Fsm3onehot
    LeetCode-二叉树的迭代遍历
    物联网AI MicroPython传感器学习 之 TDS水质检测传感器
    01_中间件
    JAVA任务流-算子执行排序算法
    基于rt-thread studio的STM32裸机开发——LED
    element ui框架(axios使用和跨域调试)
    pip 换阿里源
  • 原文地址:https://blog.csdn.net/irainsa/article/details/127941156