前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >medooze源码分析--启动服务器

medooze源码分析--启动服务器

作者头像
音视频_李超
发布2020-04-02 18:37:34
2.4K0
发布2020-04-02 18:37:34
举报
文章被收录于专栏:音视频直播技术专家

createEndpoint

当我们打开index.js 后,看到的第一个重要的 API就是createEndpoint函数了。我们就以这个 API为开头,一步一步的分析一下medooze的运行机制。

createEndpoint函数定义在 medooze-media-server 库中的 lib 目录下的 MediaServer.js 中。代码如下:

代码语言:javascript
复制
/**
 * Create a new endpoint object
 * @memberof MediaServer
 * @param {String} ip   - External IP address of server, to be used when announcing the local ICE candidate
 * @returns {Endpoint} The new created endpoing
 */
MediaServer.createEndpoint = function(ip)
{
        //Cretate new rtp endpoint
        return new Endpoint(ip);
};

它的作用是公布 ICE 本地候选者,当做一个终端。

顺着这个函数我们继续往下看,在该函数中会创建一个 Endpoint 对象。

Endpoint

medooze-media-server 库中的 lib 目录下的 Endpoint.js 文件是 Endpoint 的类文件。该类的作用如下:

代码语言:javascript
复制
/**
 * An endpoint represent an UDP server socket.
 * The endpoint will process STUN requests in order to be able to associate the remote ip:port with the registered transport and forward any further data comming from that transport.
 * Being a server it is ICE-lite.
 */
/**
 *endpoint 表示UDP服务器套接字。
 *endpoint 将处理STUN请求,以便能够将远程ip:port与注册的传输相关联,并转发来自该传输的任何进一步的通信数据。
 *作为一个服务器,它是轻量级的ICE。
*/

在创建 Endpoint 对象时,会调用它的构造函数。其代码如下:

代码语言:javascript
复制
constructor(ip)
 {
     //Store ip address of the endpoint
     this.ip = ip;
     //Create native endpoint
     this.bundle = new Native.RTPBundleTransport();
     //Start it
     this.bundle.Init();
     //Store all transports
     this.transports = new Set();
     //Create candidate
     this.candidate = new CandidateInfo("1", 1, "UDP", 33554431, ip, this.bundle.GetLocalPort(), "host");
     //Get fingerprint (global at media server level currently)
     this.fingerprint = Native.MediaServer.GetFingerprint().toString();
}

通过上面的代码可以看到 Endpoint 包括以下几个成员:

  • ip : STUN 服务器IP地址。
  • bundle:native层的Endpoint。
  • transports: 这是一个集合,用于存放所有用到的传输协议
  • candidate: ICE 候选者
  • fingerprint: 指纹,用于网络安全。

接下来,我们分别看一下 Native.RTPBundleTransport 和 CandidateInfo。

RTPBundleTransport

RTPBundleTransport 类定义在 media-server 中的 include/RTPBundleTransport.h文件中。该类的构造函数如下:

代码语言:javascript
复制
RTPBundleTransport::RTPBundleTransport()
{
        //Init values
        socket = FD_INVALID;
        port = 0;
        
        //No thread
        setZeroThread(&thread);
        running = false;
        //Mutex
        pthread_mutex_init(&mutex,0);
        pthread_cond_init(&cond,0);
}

Endpoint 类的构函数中,首先创建了 RTPBundleTransport对象,然后又调用了该对象的 Init方法,其代码如下:

代码语言:javascript
复制
int RTPBundleTransport::Init()
{
        int retries = 0;

        sockaddr_in recAddr;

        //Clear addr
        memset(&recAddr,0,sizeof(struct sockaddr_in));
        //Init ramdon
        srand (time(NULL));

        //Set family
        recAddr.sin_family      = AF_INET;

        //Get two consecutive ramdom ports
        while (retries++<100)
        {
                ...

                //Create new sockets
                socket = ::socket(PF_INET,SOCK_DGRAM,0);
                //Get random
                port = (RTPTransport::GetMinPort()+(RTPTransport::GetMaxPort()-RTPTransport::GetMinPort())*double(rand()/double(RAND_MAX)));
                //Make even
                port &= 0xFFFFFFFE;
                //Try to bind to port
                recAddr.sin_port = htons(port);
                //Bind the rtp socket
                if(bind(socket,(struct sockaddr *)&recAddr,sizeof(struct sockaddr_in))!=0)
                        //Try again
                        continue;

                ...
                Start();
                //Done
                Log("<RTPBundleTransport::Init()\n");
                //Opened
                return port;
        }

        //Error
        Error("-RTPBundleTransport::Init() | too many failed attemps opening sockets\n");

        //Failed
        return 0;
}

通过上面的代码我们可以看到, 在Init函数中,主要做了两件事儿:

  • 绑定端口号,打开sokcet服务。
  • 通过 Start() 启动了一个新的线程。对于线程的启动与所做的事情我们将在下篇文章中再做介绍。

CandidateInfo

在另外一个称为 semantic-sdp-js的项目中的lib中可以找到 CandidateInfo 类的定义。其构造函数如下:

代码语言:javascript
复制
/**
* CanditateInfo constructor
* @constructor
* @alias CandidateInfo
* @param {String} foundation
* @param {Number} componentId
* @param {String} transport
* @param {Number} priority
* @param {String} address
* @param {Number} port
* @param {String} type
* @param {String} relAddr
* @param {String} relPort
*/
constructor(foundation, componentId, transport, priority, address, port, type, relAddr, relPort) {
    this.foundation         = foundation;
    this.componentId        = componentId;
    this.transport          = transport;
    this.priority           = priority;
    this.address            = address;
    this.port               = port;
    this.type               = type;
    this.relAddr            = relAddr;
    this.relPort            = relPort;
}

其代码非常简单,就是将传入的一些参数保存起来。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • createEndpoint
  • Endpoint
  • RTPBundleTransport
  • CandidateInfo
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档