美文网首页
RTMP的connection协议

RTMP的connection协议

作者: Alfie20 | 来源:发表于2017-08-15 16:32 被阅读262次

    RTMP协议规定:
    第一步,建立一个网络连接(NetConnection):客户端和服务端的基础连通关系
    第二步:建立一个网络流(NetStream)发送多媒体的通道(只能建立一个网络连接,可以建立多个网络流)
    网络连接与网络流的关系如下图所示:



    具体而言,在ngx_rmtp中如何实现呢?
    客户端收到服务端的"connect"消息后(如前文所讲),会启动connect协议交流。但在此之前需要将处理消息的回调进行注册上,收消息回调为ngx_rtmp_recv,发送消息的回调为ngx_rtmp_send。示例代码如下:

    void ngx_rtmp_cycle(ngx_rtmp_session_t *s)
     {
        ngx_connection_t           *c;
        c = s->connection;
        c->read->handler =  ngx_rtmp_recv;
        c->write->handler = ngx_rtmp_send;
        s->ping_evt.data = c;
        s->ping_evt.log = c->log;
        s->ping_evt.handler = ngx_rtmp_ping;
        ngx_rtmp_reset_ping(s);
        ngx_rtmp_recv(c->read);
    }
    

    当收到对方发来的消息时:

    • 解析消息头
      /* parse headers /
      if (b->pos == b->start) {
      p = b->pos;
      /
      chunk basic header /
      fmt = (
      p >> 6) & 0x03;
      csid = p++ & 0x3f;
      if (csid == 0) {
      if (b->last - p < 1)
      continue;
      csid = 64;
      csid += (uint8_t)p++;
      } else if (csid == 1) {
      if (b->last - p < 2)
      continue;
      csid = 64;
      csid += (uint8_t)p++;
      csid += (uint32_t)256 * (
      (uint8_t)p++);
      }
      /
      link orphan /
      if (s->in_csid == 0) {
      /
      unlink from stream #0 /
      st->in = st->in->next;
      /
      link to new stream /
      s->in_csid = csid;
      st = &s->in_streams[csid];
      if (st->in == NULL) {
      in->next = in;
      } else {
      in->next = st->in->next;
      st->in->next = in;
      }
      st->in = in;
      h = &st->hdr;
      h->csid = csid;
      }
      ext = st->ext;
      timestamp = st->dtime;
      if (fmt <= 2 ) {
      if (b->last - p < 3)
      continue;
      /
      timestamp:
      * big-endian 3b -> little-endian 4b /
      pp = (u_char
      )×tamp;
      pp[2] = p++;
      pp[1] = p++;
      pp[0] = p++;
      pp[3] = 0;
      ext = (timestamp == 0x00ffffff);
      if (fmt <= 1) {
      if (b->last - p < 4)
      continue;
      /
      size:
      * big-endian 3b -> little-endian 4b
      * type:
      * 1b -> 1b
      /
      pp = (u_char
      )&h->mlen;
      pp[2] = *p++;
      pp[1] = *p++;
      pp[0] = p++;
      pp[3] = 0;
      h->type = (uint8_t)p++;
      if (fmt == 0) {
      if (b->last - p < 4)
      continue;
      /
      stream:
      * little-endian 4b -> little-endian 4b /
      pp = (u_char
      )&h->msid;
      pp[0] = *p++;
      pp[1] = *p++;
      pp[2] = *p++;
      pp[3] = p++;
      }
      }
      }
      /
      extended header /
      if (ext) {
      if (b->last - p < 4)
      continue;
      pp = (u_char
      )×tamp;
      pp[3] = *p++;
      pp[2] = *p++;
      pp[1] = *p++;
      pp[0] = p++;
      }
      /
      header done */
      b->pos = p;
      }
    • 判断类型,如果是"connect"的cmd消息时,其调用回调ngx_rtmp_cmd_connect_init.具体如下:
      1. 将ack_size发送对方给对方,ngx_rtmp_send_ack_size
      2. 将bandwdth发送给对方,ngx_rtmp_send_bandwidth
      3. 将chunk_size发送给对方,ngx_rtmp_send_chunk_size
      4. 将connect协议回应消息发送给对方,ngx_rtmp_send_amf,具体如下:
        static ngx_rtmp_amf_elt_t  out_inf[] = {
        { NGX_RTMP_AMF_STRING,
          ngx_string("level"),
          "status", 0 },
        { NGX_RTMP_AMF_STRING,
          ngx_string("code"),
          "NetConnection.Connect.Success", 0 },
        { NGX_RTMP_AMF_STRING,
          ngx_string("description"),
          "Connection succeeded.", 0 },
        { NGX_RTMP_AMF_NUMBER,
          ngx_string("objectEncoding"),
          &object_encoding, 0 }
        };
    
    • netconnection状态
      • "NetConnection.Connect.Success" --- 服务器连接成功
      • "NetConnection.Connect.Closed" --- 连接中断
      • "NetConnection.Connect.Failed" --- 连接失败
      • "NetConnection.Connect.Rejected" --- 没有权限

    相关文章

      网友评论

          本文标题:RTMP的connection协议

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