Skip to content

How to use Carrier API

LitingXu edited this page Oct 29, 2018 · 2 revisions

Carrier FAQ

基本概念介绍

  1. Carrier是什么

    Carrier是一个去中心化的基于F2F的消息和数据传输平台,包含两部分功能:

    • Carrier模块

      整个Carrier网络的基础模块,完成节点好友添加,删除,以及好友节点间的消息发送/接收。

    • Session模块

      基于Carrier模块消息基础上实现的一个扩展模块,完成节点好友间的数据通信。

  2. 去中心化网络

    Carrier将原来基于IPv4/IPv6寻址的TCP/IP网络,转变为一个基于Carrier节点ID(base58编码)寻址的虚拟通信网络。该虚拟网络突破了纯粹TCP/IP的由于节点间网络拓扑之间的通信限制。

  3. 节点种类

    • Boostrap节点

      此类节点必须布置在可访问的公网地址,常驻运行。并且发布节点的Public Key,供普通节点接入Carrier网络时使用。

      不会参与应用业务,对Carrier网络使用过程中完全透明。

    • 普通节点

  4. 什么是F2F通信

    “F”即是Friend,任何节点之间必须互为Friend,才能允许消息和数据通信。Friend之间的消息和数据通信完全加密。

  5. 节点UserId和Address

    • UserId

      UserId是节点的唯一标识,生成之后不会变化。请注意保存好节点的数据Cache文件。

    • Address

      Address由UserId,地址校验码(Nospam)以及Checksum组合而成。可以通过ela_get_address()接口获取当前节点的Address。只有在调用ela_add_friend时才需要对端的节点Address,节点Address必须通过第三方渠道获取。

  6. Address的作用

    为防止恶意被添加Friend,Carrier增加了Address,用于被其他节点添加为Friend。如果受到骚扰,可以通过调用ela_set_nospam()接口重新设置Address,之前的Address不会再接收到任何通知。

如何使用Carrier模块

  1. Carrier创建与运行

    a. 调用ela_new()创建初始化Carrier,创建Carrier实例。

    b. 调用ela_run()运行Carrier节点。

  2. Carrier节点的表示状态的几个回调

    • ready

      节点准备好之后触发此回调。应用必须要等到这个回调,才可以调用api与friend进行通信。

    • connection_status

      节点的连接状态变化时触发此回调。

    • friend_connection

      好友状态改变时触发此回调。

  3. 如何添加Friend

    通过调用ela_add_friend添加friend,需要传入对端的address。必须要对端online才可以调用成功

    当有节点请求添加好友时,接收端会触发friend_request,可以选择调用ela_accept_friend()接受请求,或者直接忽略不做任何处理。

  4. 如何给好友发送消息

    调用ela_send_friend_message()给好友发送消息。调用此方法时自身节点必须是ready的状态,对端必须是online的状态。

如何使用Session模块

  1. Session是什么

    Carrier Session是一个Stream容器。一个Session中可以添加多个Stream(最多允许4个),但是每添加一个Stream,消耗的系统资源就会成倍增加,因此Stream数量根据需求适当创建,不是越多越好。

  2. Sesion与Carrier初始化的先后顺序

    必须先有Carrier实例才允许调用 ela_session_init()接口初始化session模块。 可以在调用ela_run()接口前调用ela_session_init()初始化Session模块,也可以在ElaCallbacks回调实现中视需要调用ela_session_init()接口初始化session模块。

  3. 调用Session模块其他接口的必备条件

    • 必须调用ela_session_init()接口初始化session模块
    • 必须保证Session双方节点互为Friend
    • 必须保证对端节点处于Online状态(此步骤对ela_session_request/reply_request/start必须)
  4. Session创建过程

    • 发起端

      a. 当前节点调用ela_session_new()创建Session实例

      b. 调用ela_session_add_stream根据需求添加Stream

      c. 等待Stream状态为initilized之后,调用ela_session_request()接口发送给对端好友

      d. 对端好友reply session之后,会触发session_request_oncomplete回调,此时可以调用ela_sesssion_start()进行session协商,开始进行session通道创建。

      e. 等待Stream状态为connected后,可以通过ela_write_stream()进行数据传输。

    • 接收端

      a. 在session_request callback触发提醒收到好友session request,调用ela_session_new()创建Session实例。

      b. 调用ela_session_add_stream根据需求添加Stream,Stream的option必须与发起端一致。

      c. 等待Stream状态为initilized之后,通过ela_session_reply_request()接口响应发起端的的session request。

      d. 等待Stream状态为tansport ready后,调用ela_sesssion_start()进行session协商,开始进行session通道创建。

      e. 等待Stream状态为connected后,可以通过ela_write_stream()进行数据传输。

    数据通信完成之后,调用ela_session_close()接口关闭Session。 调用ela_session_close()接口前,建议调用接口ela_session_remove_stream() 删除Session容器内所有stream实例。

    Session创建过程时序图:

时序图

  1. Stream的生命周期

    Session容器内的stream有以下几个状态:

    • Initalized --- 调用ela_session_add_stream()接口后异步触发
    • Transport ready --- 调用ela_session_request/reply_request()接口后异步触发
    • Connecting --- 调用ela_session_start()接口内触发
    • Connected --- 调用ela_session_start()接口后异步触发
    • Deactivated --- 调用ela_session_start()接口后异步触发
    • Closed --- 调用ela_session_closed()关闭session实例过程内或者对端好友关闭session时触发
    • Failed --- 以上过程中出错后

Carrier错误分析

  1. ela_get_error()接口

    如果在调用Carrier接口后出错,可以通过ela_get_error()接口获取错误码,分析错误原因。

Carrier中的线程

  1. Carrier运行时ElaCallbacks触发线程

    所有跟Carrier实例相关的ElaCallbacks都由调用ela_run()接口的线程触发,包括friend request/added/removed/friend_connection, 以及 message接收和invite/invite reply等。

  2. 可以用单线程(一个线程)完成基于Carrier的应用吗

    可以,但必须用异步的思路考虑应用逻辑。可以在主线程创建Carrier实例以及ela_run()接口运行Carrier。 应用业务可经过切分后可以放置到on_idle callback中分片段处理。

  3. 可以在Carrier Callbacks回调中调用Carrier接口吗

    可以,只要满足该接口的调用依赖条件,可以在Callbacks中调用Carrier接口。例如可以在friend_request callback中调用ela_accept_friend()接口接受对端为fiend。

  4. Session模块中ElaStreamCallbacks触发线程

    ela_session_new()接口内部会创建一个worker线程,专门处理该Session相关的数据接收和ElaStreamCallbacks中的回调触发, 包括stream_data()接收流数据。

  5. 可以在Session相关ElaStreamCallbacks回调中调用Carrier/Session接口吗

    可以,只要满足被调用接口的调用依赖条件,可以在Callbacks中调用Carrier/Session接口。例如可以在session_request_oncomplete callback中调用ela_session_start来建立Session连接。

  6. sesssion_request 回调是在哪个线程被触发调用的

    session_request和session_request_oncomplete回调函数都是在Carrier模块调用ela_run()接口的线程被触发调用, 不会在Session相关的worker线程触发调用。