srs 服务器在客户端断开连接后,服务器代码跟踪分析

最近有个疑问,当客户端主动断开连接的时候srs服务器是怎么主动断开的,gdb跟踪。

我发现的有两种情况:

1.客户端主动断开连接情况:客户端连接服务器后,一直ret = do_publishing(source, &trd);这个函数哪里等待(代码如下),

当客户端主动断开后,就继续运行后面的 trd.stop(); 这个trd.stop()才是服务器断开客户端退出线程的关键地方。


int SrsRtmpConn::publishing(SrsSource* source)
{
    int ret = ERROR_SUCCESS;

    if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) {
        srs_error("check publish_refer failed. ret=%d", ret);
        return ret;
    }
    srs_verbose("check publish_refer success.");

    if ((ret = http_hooks_on_publish()) != ERROR_SUCCESS) {
        srs_error("http hook on_publish failed. ret=%d", ret);
        return ret;
    }

    bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost);
    if ((ret = acquire_publish(source, vhost_is_edge)) == ERROR_SUCCESS) {
        // use isolate thread to recv,
        // @see: https://github.com/ossrs/srs/issues/237
        SrsPublishRecvThread trd(rtmp, req,
            st_netfd_fileno(stfd), 0, this, source,
            client_type != SrsRtmpConnFlashPublish,
            vhost_is_edge);

        srs_info("start to publish stream %s success", req->stream.c_str());
        ret = do_publishing(source, &trd);

        srs_trace("===========>>>>>>>>>>will trd.stop");
        // stop isolate recv thread
        trd.stop();
    }
   
    // whatever the acquire publish, always release publish.
    // when the acquire error in the midlle-way, the publish state changed,
    // but failed, so we must cleanup it.
    // @see https://github.com/ossrs/srs/issues/474
    // @remark when stream is busy, should never release it.
    if (ret != ERROR_SYSTEM_STREAM_BUSY) {
        release_publish(source, vhost_is_edge);
    }

    http_hooks_on_unpublish();

    return ret;
}


2.客户端不正常退出后,服务器怎么断开连接的?

服务器会触发以写错误的信号 if (errno == EINTR),如下面代码

ssize_t st_writev(_st_netfd_t *fd, const struct iovec *iov, int iov_size,
    st_utime_t timeout)
{
  ssize_t n, rv;
  size_t nleft, nbyte;
  int index, iov_cnt;
  struct iovec *tmp_iov;
  struct iovec local_iov[_LOCAL_MAXIOV];

  /* Calculate the total number of bytes to be sent */
  nbyte = 0;
  for (index = 0; index < iov_size; index++)
    nbyte += iov[index].iov_len;

  rv = (ssize_t)nbyte;
  nleft = nbyte;
  tmp_iov = (struct iovec *) iov; /* we promise not to modify iov */
  iov_cnt = iov_size;

  while (nleft > 0) {
    if (iov_cnt == 1) {
      if (st_write(fd, tmp_iov[0].iov_base, nleft, timeout) != (ssize_t) nleft)
 rv = -1;
      break;
    }
    if ((n = writev(fd->osfd, tmp_iov, iov_cnt)) < 0) {
      if (errno == EINTR)
 continue;
      if (!_IO_NOT_READY_ERROR) {
 rv = -1;
 break;
      }
    } else {
      if ((size_t) n == nleft)
 break;
      nleft -= n;

后面的代码省略


然后发生接下来下面代码的:return ERROR_SOCKET_WRITE;

int SrsStSocket::writev(const iovec *iov, int iov_size, ssize_t* nwrite)
{
    int ret = ERROR_SUCCESS;
   
    ssize_t nb_write = st_writev(stfd, iov, iov_size, send_timeout);
    if (nwrite) {
        *nwrite = nb_write;
    }
   
    // On success a non-negative integer equal to nbyte is returned.
    // Otherwise, a value of -1 is returned and errno is set to indicate the error.
    if (nb_write <= 0) {
        // @see https://github.com/ossrs/srs/issues/200
        if (nb_write < 0 && errno == ETIME) {
            return ERROR_SOCKET_TIMEOUT;
        }
       
        return ERROR_SOCKET_WRITE;
    }
   
    send_bytes += nb_write;
   
    return ret;
}


最后也回到了1.客户端主动断开连接的这一样步骤,运行 trd.stop(); 退出线程


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在CentOS上部署SRS流媒体服务器,可以按照以下步骤进行操作: 1. 首先,从GitHub上下载SRS的压缩文件srs-3.0release.zip,并解压缩该文件。可以使用以下命令: ``` unzip srs-3.0release.zip ``` 2. 在`/usr/local`目录下创建一个名为`srs3.0`的文件夹,并将解压缩后的srs-3.0release文件夹中的所有内容复制到`srs3.0`中。可以使用以下命令: ``` mkdir /usr/local/srs3.0 cp -ri srs-3.0release/* /usr/local/srs3.0 ``` 3. 进入`srs3.0/trunk`目录,并执行`./configure && make`命令来编译SRS。可以使用以下命令: ``` cd /usr/local/srs3.0/trunk ./configure && make ``` 4. 最后,执行`./objs/srs -c conf/srs.conf`命令来启动SRS服务。可以使用以下命令: ``` ./objs/srs -c conf/srs.conf ``` 这样,你就成功在CentOS上部署和启动了SRS流媒体服务器。请确保按照上述步骤进行操作,并根据实际情况调整命令中的路径和文件名。 #### 引用[.reference_title] - *1* *2* [centos7 部署安装SRS流媒体服务器](https://blog.csdn.net/zhengTornado/article/details/115451644)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [基于centos 用srs 快速搭建一个直播服务器](https://blog.csdn.net/sinat_26143945/article/details/105173786)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值