LinkRTC API 说明

版本编号: 0.1
构建日期: 2016-02-22

目录

自述

Read the Docs 构建状态:

https://readthedocs.org/projects/linrtc-api-manual-zh/badge/?version=latest https://readthedocs.org/projects/linrtc-api-manual-zh/badge/?version=master https://readthedocs.org/projects/linrtc-api-manual-zh/badge/?version=develop

目的

该项目用于形成 LinkRTC 的 API 说明文档。

LinkRTC 的用户通过阅读该文档,了解开发过程和接口使用方式。

构建

该项目基于 sphinx-doc 构建,请参考 sphinx-doc 获知具体的构建步骤。

概念

账号和项目

用户在第一次使用 LinkRTC 之前,必须先注册一个账户(Account)。

账户的作用 blablabla...

一个账户名下可以建立多个项目(Project)。 项目的作用 blabla...

blockdiag Account Project 1..n

WebRTC

blabla...

SIP

blabla...

呼出过程

定义

呼出过程是指:
具有 WebRTC 功能的浏览器/客户端通过 LinkRTC 呼叫 SIP 终端/服务器的过程。
呼出过程的参与者有:
  • 具有 WebRTC 功能的浏览器/客户端
  • 用户应用服务程序
  • LinkRTC 服务器
  • 被叫 SIP 电话

状态变化

外呼过程中,呼叫的状态有:
  • pendingLinkRTC 准备进行呼出,但是呼出还没有真正开始的阶段。这是呼叫的开始状态。
  • callingLinkRTC 向目标 SIP 端点发出了 INVITE 指令。
  • ringing:目标 SIP 端点向 LinkRTC 发出了 RINGING 指令。这通常出现在被叫电话振铃的时候。
  • confirmed:目标 SIP 端点向 LinkRTC 发出了 200 OK 状态码。这通常表示被叫电话接听,双方可以建立通话。
  • dropped:呼叫失败或者通话结束。这是呼叫的结束状态。

digraph outgoing_call_state { begin [shape=point] end [shape=doublecircle] begin -> pending [label="准备呼叫"] pending -> calling [label="开始呼叫"] pending -> dropped [label="禁止呼叫"] calling -> ringing [label="回铃"] calling -> confirmed [label="接通"] calling -> dropped [label="呼叫失败"] ringing -> confirmed [label="接通"] ringing -> dropped [label="呼叫失败"] confirmed -> dropped [label="通话结束"] dropped -> end }

步骤说明

以下分步骤说明呼出过程。

在顺序图中:
  • c1 代表:具有 WebRTC 功能的浏览器/客户端 c1
  • appserver 代表:用户应用服务程序
  • linkrtc 代表:LinkRTC 服务器
  • s1 代表:被叫 SIP 端点 s1
1. 请求呼出

1.1. 客户端 c1LinkRTC 提交呼出请求,在这个请求中,他要求以主叫号码 x 、被叫号码 y 的名义,向 SIP 端点 s1 发起呼叫。

1.2. LinkRTC 收到请求后,询问用户应用服务程序是否允许这次呼出。

1.2.1. 如果允许: LinkRTC 继续后续的呼出过程。

1.2.2. 如果拒绝: LinkRTC 结束此次呼出过程,并通知客户端呼出被拒绝。

请求呼出,并被允许

blockdiag c1 appserver linkrtc s1 make_call: from=x, to=y, target=s1 notify: call outgoing command: allowed return: continue wait continue

请求呼出,并被拒绝

blockdiag c1 appserver linkrtc s1 make_call: from=x, to=y notify: call outgoing command: disallowed! return: refused wait break
2. 呼叫 SIP

2.1. LinkRTC 以主叫号码 x 、被叫号码 y 的名义,向 s1 发起 SIP 呼叫。

2.2. LinkRTC 将呼叫状态的变化 同时 通知 客户端 c1 和 用户应用服务程序,直到呼叫建立或者失败。

SIP 呼叫成功

blockdiag c1 appserver linkrtc s1 call state: pending call state: pending INVITE call state: calling call state: calling RINGING call state: ringing call state: ringing OK with SDP call state: confirmed(with S DP) call state: confirmed(with SDP) continue wait wait for answer continue

SIP 呼叫失败

blockdiag c1 appserver linkrtc s1 call state: pending call state: pending INVITE call state: calling call state: calling 486 Busy Here call state: disconnected call state: disconnected continue wait break
3. 媒体连接

如果呼叫成功,客户端 c1 会收到 LinkRTC 转发的对端 SIP 终端的 SDPc1 根据该 SDP ,使用 WebRTC 建立点对点媒体通道。

4. 呼叫结束

SIP 终端 s1LinkRTC 发送 SIP BYE 指令;或者 c1LinkRTC 发结束命令,都会导致呼叫的结束。

s1 主动结束呼叫时, LinkRTC 会将通话状态变化 同时 通知 c1 和 用户应用服务程序。

SIP 一方结束呼叫

blockdiag c1 appserver linkrtc s1 BYE call state: disconnected call state: disconnected ACK continue

WebRTC 一方结束呼叫

blockdiag c1 appserver linkrtc s1 end call BYE call state: disconnected ACK continue

呼入过程

定义

呼入过程是指:
SIP 终端/服务器向 LinkRTC 发起呼叫, LinkRTC 将呼叫交换到具有 WebRTC 功能的浏览器/客户端的过程。
呼出过程的参与者有:
  • 主叫 SIP 电话
  • LinkRTC 服务器
  • 具有 WebRTC 功能的浏览器/客户端
  • 用户的 Web 服务器

状态变化

外呼过程中,呼叫的状态有:
  • pendingLinkRTC 收到了来自 SIP 端点的呼入,单还没有决定如何处理。
  • calling:用户的程序告知 LinkRTC 将呼入选择到某一客户端,LinkRTC 开始呼叫这个客户端。
  • ringing:客户端收到了 LinkRTC 的呼叫。
  • confirmed:客户端接受了呼叫,双方可以建立通话。
  • dropped:呼叫失败或者通话结束。这是呼叫的结束状态。

digraph incoming_call_state { begin [shape=point] end [shape=doublecircle] begin -> pending [label="呼入"] pending -> calling [label="确定了目标客户端"] pending -> dropped [label="呼叫禁止"] calling -> ringing [label="客户端收到呼叫"] calling -> dropped [label="呼叫失败"] ringing -> confirmed [label="接通"] ringing -> dropped [label="呼叫失败"] confirmed -> dropped [label="通话结束"] dropped -> end }

步骤说明

以下分步骤说明呼入过程。

在顺序图中:
  • s1 代表:主叫叫 SIP 端点 s1
  • linkrtc 代表:LinkRTC 服务器
  • webserver 代表:用户的 Web 服务器
  • c1 代表:具有 WebRTC 功能的浏览器/客户端 c1
1. 呼入选择

1.1. LinkRTC 收到了来自 s1 的呼入请求

1.2. LinkRTCs1 回复 SIP 状态码 100 TRYING

1.3. LinkRTC 询问用户的服务程序,是否允许这个呼入,以及要将这个呼入交换到哪个客户端

1.3.1 如果用户的服务程序禁止该呼入,则结束呼叫过程

1.3.2 如果用户的服务程序指定了目标客户端,则继续后续过程

呼入选择

blockdiag s1 linkrtc webserver c1 INVITE TRYING notify: incoming_call command: switch to 'c1' continue

呼入拒绝

blockdiag s1 linkrtc webserver c1 INVITE TRYING notify: incoming_call command: drop! 403 Forbidden break
2. 呼叫客户端

2.1. LinkRTC 向目标客户端 c1 发起呼叫

2.1.1. 如果 c1 无法收到呼叫指令,则结束此次呼入过程,并通知用户的应用服务器。

2.1.2. 如果 c1 收到了呼叫,通知主叫 SIP 和用户的应用服务器,然后等待 c1 的响应。

2.2. 然后等待 c1 的响应。

2.2.1. 如果 c1 拒绝,或者超时无响应,则结束此次呼入过程,并通知用户的应用服务器。

2.2.2. 如果 c1 接受呼入,则通知主叫 SIP 和用户的应用服务器,继续后续步骤。

呼叫客户端成功

blockdiag s1 linkrtc webserver c1 INVITE: from='x', to='y' TRYING notify: incoming call(from=' x', to='y') command: switch to 'c1' notify: state=calling incoming call: from='x', to='y' return: accept notify: accepted 200 OK continue wait wait continue

呼叫客户端失败

blockdiag s1 linkrtc webserver c1 INVITE: from='x', to='y' TRYING notify: incoming call(from=' x', to='y') command: switch to 'c1' notify: state=calling incoming call: from='x', to='y' notify: state=dropped 480 Temporarily Unavailable continue wait break
3. 媒体连接

如果呼叫成功,客户端 c1 会收到 LinkRTC 转发的对端 SIP 终端的 SDPc1 根据该 SDP ,使用 WebRTC 建立点对点媒体通道。

4. 呼叫结束

SIP 终端 s1LinkRTC 发送 SIP BYE 指令;或者 c1LinkRTC 发结束命令,都会导致呼叫的结束。

s1 主动结束呼叫时, LinkRTC 会将通话状态变化 同时 通知 c1 和 用户的 Web 服务器。

SIP 一方结束呼叫

blockdiag s1 linkrtc webserver c1 BYE call state: disconnected call state: disconnected ACK continue

WebRTC 一方结束呼叫

blockdiag s1 linkrtc webserver c1 end call BYE call state: disconnected ACK continue

服务器 API

目录

服务器 API 介绍

服务器 API 用于 LinkRTC 后台与用户的应用服务程序之间的通信。

它们之间的通信以 HTTP 的形式在互联网上进行。

LinkRTC 与 用户的应用服务程序 既充当 HTTP 服务器又充当 HTTP 客户端 : 以客户端的身份向对方发送请求,同时也以服务器的身份接受对方的请求。

digraph server_http { linkrtc [label="api.linkrtc.com"] userapp [label="用户应用程序服务"] linkrtc -> userapp [label="HTTP or HTTPS" color=blue fontcolor=blue] userapp -> linkrtc [label="force HTTPS" color=green fontcolor=green] }

设计原则
  1. 基于 HTTP 1.1
  2. 双方互为 HTTP 服务器/客户端,双向访问。
  3. 采用 Restful 形态的 Web API
  4. 消息提使用 UTF-8 编码的 JSON 格式文本记录结构化数据。
  5. LinkRTC 只接受 HTTPS 加密连接; LinkRTC 向用户应用程序服务发送请求时允许使用不加密的 HTTP 连接。
  6. 用户应用服务程序向 LinkRTC 发送的请求需要通过 HTTP Basic AuthenticationHTTP 基本认证)。
  7. LinkRTC 向用户应用服务程序发送的请求带有消息签名。
格式规范
HTTP 地址

用户应用服务程序调用 LinkRTC 的 API 时候,URL 的路径部分的格式是:

/<api_version>/sapi/*

其中 api_versionLinkRTC API 的版本,跨版本访问可能有兼容问题。

sapi 表示服务应用程序接口( Service Application Program Interface ),所有的服务器API的访问路径均具有该部分。

HTTP 头和内容
普通请求与回复

POSTPUT 请求、以及回复的正文部分 必须 是 采用 UTF-8 编码的 JSON 格式字符串, Content-Type 头域的值应是 application/json

例如:

用户应用程序服务发出的请求:

POST /v0.l/sapi/webrtcclient/create HTTP/1.1
Host: api.linkrtc.com
Content-Type: application/json; charset=utf-8
Content-Length: xxx

{
  "capability": {
    "audio": true,
    "video": false
  },
  "userData": "client-01"
}

api.linkrtc.com 的回复:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: xxx

{
  "id": "5",
  "wskey": "fg430mu3ojfg398u4",
  "expires": 3600
}
空请求与回复

如果 POSTPUT 请求不包含内容,或回复不包含内容, 其 Content-Length 头域的值应为 0,例如:

请求:

POST /v0.1/sapi/ping HTTP/1.1
Host: api.linkrtc.com
Content-Length: 0

回复:

HTTP/1.1 200 OK
Content-Length: 0
HTTP 状态码
200 OK

如果API调用成功,被调用方应返回状态码 200 OK

401 Unauthorized

如果 LinkRTC 收到的服务器 API 请求中,没有正确的身份验证信息,就返回这个状态码。

参见 身份认证

500 Internal Server Error

如果服务器在响应API调用期间出现错误,或者出现意料之外的情况,应返回该状态码。

LinkRTC 在许多情况下,会提供具体的错误编码以及错误信息,这些错误信息用 JSON 对象格式存放在回复数据的内容部分。 其中 code 属性记录错误编码, text 属性记录错误文本信息。

如:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8
Content-Length: xxx

{"code": 10013, "text": "calee not allowed"}

注意

LinkRTC 后台服务无法在所有情况下都提供 JSON 格式错误信息。 调用方可以根据 Content-Type 进行判断。

其它

其它 Status Code 均遵照 RFC 2616 的定义

安全

数据加密

用户应用服务程序向 LinkRTC 后台发送请求时, 必须 使用 HTTPS 连接。

身份认证

用户应用服务程序向 LinkRTC 发送的请求需要提供 HTTP Basic AuthenticationHTTP 基本认证)信息。 LinkRTC 根据认证信息中的用户名和密码对调用者进行身份认证。

例如,某用户在 LinkRTC 拥有一个 SIDProject1项目 , 该项目的访问密码是 abc123,那么,用户应用服务程序发送的 HTTP 请求 必须 带有正确的 Authorization 头:

GET /v0.1/sapi/webrtcclient/5 HTTP/1.1
Host: api.linkrtc.com
Authorization: Basic UHJvamVjdDE6YWJjMTIz

如果用户应用服务程序缺少或者没有提供正确 Authorization 信息, LinkRTC 将返回 401 Unauthorized

消息签名

LinkRTC 在其向用户应用服务程序发送的 HTTP 请求中附加了签名和时间戳。 用户应用服务程序可以对签名进行验证,防止冒充的消息。

签名算法所需参数有:
  • Project SID: 该 项目SID
  • AppSecret: 该 项目 的反向访问密码(与 身份认证 过程中所使用的密码不同)
  • TimeStamp: Unix 时间戳
计算步骤:
  1. 分别计算上述三个字符串参数的MD5散列值的十六进制表达式(字母部分 大写 )。
  2. 将这三个散列值按照字符顺序排序后,依次首尾连接,得到一个新字符串。
  3. 计算上一个步骤中得到的新字符串的MD5散列值的十六进制表达式(字母部分 大写 ),即为签名。
签名和Unix时间戳被附加在 HTTP 请求的头域中,
  • 时间戳的头域: X-LinkRTC-Signature
  • 签名的头域: X-LinkRTC-Timestamp

带有签名信息的 HTTP 请求形如:

POST /your/script.php HTTP/1.1
Host: your.app.com
Content-Type: application/json; charset=utf-8
Content-Length: xxx
X-LinkRTC-Timestamp: 1453543759
X-LinkRTC-Signature: E6E157A9FA805921DA12A86A40CC2A15

{
  "type": "xxxx",
  "data": "xxxx",
}
签名算法
在下面的代码片段中:
  • 项目 SIDProject1
  • AppSecret123abc
  • Timestamp1453543759

得到的签名应该是:

E6E157A9FA805921DA12A86A40CC2A15

以下几个小节是几种常见语言的签名算法实现代码片段:

Java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;

public class SignatureExample {

  public static String byteArrayToHex(byte[] byteArray) {
      char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
      char[] resultCharArray = new char[byteArray.length * 2];
      int index = 0;
      for (byte b : byteArray) {
          resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
          resultCharArray[index++] = hexDigits[b & 0xf];
      }
      return new String(resultCharArray);
  }

  public static String md5Str(String input)
          throws NoSuchAlgorithmException {
      MessageDigest messageDigest = MessageDigest.getInstance("MD5");
      byte[] inputByteArray = input.getBytes();
      messageDigest.update(inputByteArray);
      byte[] resultByteArray = messageDigest.digest();
      return byteArrayToHex(resultByteArray);
  }

  public static void main(String[] args)  {
      try {
          String projectSid = "Project1";
          String appSecret = "123abc";
          String timestamp = "1453543759";

          ArrayList<String> tmpList = new ArrayList<String>();
          tmpList.add(md5Str(projectSid);
          tmpList.add(md5Str(appSecret);
          tmpList.add(md5Str(timestamp);
          Collections.sort(tmpList);

          String signature = md5Str(String.join("", tmpList));

          System.out.format("signature = %s", signature);
      } catch (NoSuchAlgorithmException e) {
          e.printStackTrace();
      }
  }

}
NodeJs
var crypto = require('crypto');

(function() {
  var projectSid = "Project1";
  var appSecret = "123abc";
  var timestamp = "1453543759";

  var md5Str = function(s) {
    var hasher = crypto.createHash('md5');
    hasher.update(s);
    return hasher.digest('hex').toUpperCase();
  }

  var tmpArr = [projectSid, appSecret, timestamp].map(md5Str);
  tmpArr.sort();
  var signature = md5Str(tmpArr.join(''));

  console.log(`signature = ${signature}`);
})();
Php
<?php
$project_sid = 'Project1';
$app_secret = '123abc';
$timestamp = '1453543759';

function md5_str($s) {
    return strtoupper(md5($s));
}

$tmp_arr = array_map(md5_str, array($project_sid, $app_secret, $timestamp));
sort($tmp_arr, SORT_STRING);

$signature = md5_str(implode($tmp_arr));

echo('signature = ' . $signature);
Python
from hashlib import md5

project_sid = b'Project1'
app_secret = b'123abc'
timestamp = b'1453543759'

def md5_str(s):
  return md5(s).hexdigest().upper().encode()

signature = md5_str(b''.join(sorted(map(md5_str, [project_sid, app_secret, timestamp]))))

print('signature = %s' % signature)

WebRTC 客户端管理 API

获取客户端列表
POST /v0.1/sapi/webrtcclient/list

获取 sapi.WebRtcClient 实例列表

Request JSON Object:
 
  • page (int) – 要返回的页码。如果不指定,默认为1(从1开始)。
  • perPage (int) – 每页长度。如果不指定,服务器采用其默认设置。
Response JSON Object:
 
  • currentPage (int) – 当前返回结果的页码(从1开始)。
  • perPage (int) – 每页长度。
  • totalPages (int) – 总页数。
  • totalEntries (int) – 总条目数。
  • entries (list) – sapi.WebRtcClient 对象列表。

举例

客户端调用:

POST /v0.1/sapi/webrtcclient/list HTTP/1.1
Host: api.linkrtc.com
Content-Type: application/json; charset=utf-8
Content-Length: xxx

{
  "page": 1,
  "perPage": 20
}

服务器回复:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: xxx

{
  "currentPage": 1,
  "perPage": 20,
  "totalPages": 3,
  "totalEntries": 57,
  "entries": [
    {"..": "...", "..": "...", "..": "..."},
    {"..": "...", "..": "...", "..": "..."}
  ]
}
获取客户端详情
GET /v0.1/sapi/webrtcclient/(str: webrtcclient_id)/detail

获取指定 id (webrtcclient_id) 的 sapi.WebRtcClient 实例的详情

Response JSON Object:
 

举例

客户端调用:

GET /v0.1/sapi/webrtcclient/1001/detail HTTP/1.1
Host: api.linkrtc.com

服务器回复:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: xxx

{
  "data": {
    "id": "xxxxx",
    "from": "xxxxx",
    "to": "xxxxx",
    "...": "..."
  }
}
新建客户端
POST /v0.1/sapi/webrtcclient/create

新建一个 sapi.WebRtcClient 对象

Request JSON Object:
 
Response JSON Object:
 
删除客户端
POST /v0.1/sapi/webrtcclient/(str: webrtcclient_id)/remove

删除指定 id (webrtcclient_id) 的 sapi.WebRtcClient 实例

呼叫 API

获取呼叫列表
GET /v0.1/sapi/call

获取当前正在进行的呼叫 sapi.Call 实例列表

Request JSON Object:
 
  • page (int) – 要返回的页码。如果不指定,默认为1(从1开始)。
  • perPage (int) – 每页长度。如果不指定,服务器采用其默认设置。
Response JSON Object:
 
  • currentPage (int) – 当前返回结果的页码(从1开始)。
  • perPage (int) – 每页长度。
  • totalPages (int) – 总页数。
  • totalEntries (int) – 总条目数。
  • entries (list) – sapi.Call 对象列表。
获取呼叫详情
GET /v0.1/sapi/call/(str: call_id)/detail

获取 IDcall_id 的呼叫的详情。

Response JSON Object:
 
  • data – 呼叫详细信息( sapi.Call 对象)。如果该 call_id 呼叫不存在,返回 null
中断呼叫
POST /v0.1/sapi/call/(str: call_id)/drop

中断 IDcall_id 的呼叫,无论它处于什么状态。

出方向呼叫的允许/禁止
POST /v0.1/sapi/call/(str: call_id)/allow

允许/禁止 IDcall_id 的出方向呼叫

Request JSON Object:
 
  • allowd (bool) – 是否允许

详见 呼出过程

注意

仅对 出方向 呼叫有效

入方向呼叫交换到客户端
POST /v0.1/sapi/call/(str: call_id)/switch

将入方向呼叫交换到指定的客户端

Request JSON Object:
 
  • client_type (str) – 客户端类型,目前仅支持 WebRtc
  • client_id (str) – 客户端 ID

详见 呼入过程

注意

仅对 入方向 呼叫有效

通知 API

LinkRTC 后台服务通过通知 API 将通知类型的消息数据 POST 到用户的应用服务程序。

digraph notify_api { a [label="api.linkrtc.com"] b [label="http://your.app.com/your/script.php"] a -> b [label="POST"] }

用户应用服务程序通过这些通知数据判断呼叫或者客户端的状态,以便对其进行控制。

接收通知消息的 URL 通过 用户控制台 设置。

注意

在通知 API 中, LinkRTC 作为 HTTP 客户端,用户应用服务程序作为 HTTP 服务器。

所以: 开发者的 Web 服务程序需要向 LinkRTC 提供访问地址!

通知消息的内容是 JSON 对象格式。

JSON 对象的最外层包括两个属性:
  • type: 消息类型字符串。
  • data: 消息参数,其数据类型随事件类型不同而各异。

例如:

{
    "type": "call.CallStateChanged",
    "data": {
        "call": {
            "id": "2341",
            "dir": "incoming",
            "from": "13283484795",
            "to": "400666255343",
            "...": "... ..."
        }
    }
}

本节文档使用面向对象语言类型定义的伪代码形式,描述通知消息 data 部分的数据结构。

呼叫状态变化
type:event.CallStateChanged
class sapi.event.CallStateChanged
call

状态发生变化的呼叫

返回类型:sapi.Call

举例:

ID2341 的入方向呼叫产生:

POST /your/script.php HTTP/1.1
Host: your.company.com
Content-Type: application/json; charset=utf-8
Content-Length: xxx
X-LinkRTC-Timestamp: 1453543759
X-LinkRTC-Signature: E6E157A9FA805921DA12A86A40CC2A15

{
    "type": "event.CallStateChanged",
    "data": {
        "call": {
            "id": "2341",
            "dir": "incoming",
            "current_state": "pending",
            "...": "... ..."
        }
    }
}

警告

当用户应用服务程序收到呼叫状态变化事件通知中, data 部分的 sapi.Call 对象的当前状态属性 sapi.Call.current_state 值为 待定 (pending) , 且呼叫方向属性 sapi.Call.dir 值为 出方向 (outgoing) 时, 用户应用服务程序需要在呼叫超时或者被放弃之前调用 POST /v0.1/sapi/call/(str:call_id)/allow 允许此次呼叫,方可使出方向呼叫继续进行。

同理,当 data 部分的 sapi.Call 对象的当前状态属性 sapi.Call.current_state 值为 待定 (pending) , 且呼叫方向属性 sapi.Call.dir 值为 入方向 (incoming) 时, 用户应用服务程序需要在呼叫超时或者被放弃之前调用 POST /v0.1/sapi/call/(str:call_id)/switch 允许此次呼叫,方可使入方向呼叫继续进行。

WebRTC 客户端连接状态变化

WebRTC 客户端连接建立或者连接断开

type:event.WebRtcClientConnectStateChanged
class sapi.event.WebRtcClientConnected
connected
  • true: 连接建立
  • false: 连接断开
返回类型:bool
client

连接状态发生变化的客户端

返回类型:sapi.WebRtcClient

举例:

IDsx3kerjsWebRTC 客户端建立连接:

POST /your/script.php HTTP/1.1
Host: your.company.com
Content-Type: application/json; charset=utf-8
Content-Length: xxx
X-LinkRTC-Timestamp: 1453543759
X-LinkRTC-Signature: E6E157A9FA805921DA12A86A40CC2A15

{
    "type": "event.WebRtcClientConnectStateChanged",
    "data": {
        "connected": true,
        "client": {
            "id": "sx3kerjs",
            "..": "....",
            "...": "... ..."
        }
    }
}

数据结构定义

在服务器API中,用 JSON 对象格式记录各个实体的属性。

本章节使用面向对象语言类型定义的伪代码形式描述各个实体以及其属性的含义与数据类型。

注意

事件通知数据的结构定义不在本章,具体请参见 通知 API

WebRTC 客户端
class sapi.WebRtcClient

该数据结构用于记录一个 WebRTC 客户端实例的相关信息。

id

客户端ID

返回类型:str
project

该客户端所属的 项目SID

返回类型:str
wskey

客户端 WebSocket 连接关键字

返回类型:str
呼叫信息
class sapi.Call
id

呼叫ID

返回类型:str
dir

呼叫方向

返回类型:str
定义:
方向 表达式
呼入 incoming
呼出 outgoing
current_state

当前呼叫状态,详见 呼入过程呼出过程

返回类型:str
定义:
状态 表达式
待定 pending
呼叫中 calling
等待应答 ringing
已接通 confirmed
结束 dropped
prior_state

上一个呼叫状态,其属性值含义与 current_state 一致。

返回类型:str

注解

当呼叫刚刚建立时,其当前状态 current_statependingprior_state 值是 null

from
返回类型:str
to
返回类型:str

客户端 API

目录

介绍

客户端 API 用于 LinkRTC 后台与具有 WebRTC 功能的浏览器/客户端之间的通信。

它们之间的通信基于 WebSocket ,遵照 JSON-RPC 2.0 标准。

在浏览器上,开发者可以通过 JavaScript 脚本使用这些 API 。

LinkRTC 与 浏览器/客户端 既充当调用者,用充当被调用者 ,所以,它们之间的通信是双向的。

设计原则
  1. 使用经过SSL/TLS加密的 WebRTC (即 wss)建立连接。
  2. 采用远程方法调用通信模式,遵照 JSON-RPC 2.0 标准,但是不支持批处理模式。
  3. 双方均可双向调用。
  4. 服务器同一时间只响应一个客户端的一个调用。
格式规范
URL

WebRTC 客户端访问这个 URL 建立 WebSocket 连接:

GET /v0.1/capi/(str: project_id)

IDproject_id 的项目的 WebRTC 客户端建立基于 WebSocketJSON-RPC 连接。

Query Parameters:
 
  • key (str) – 客户端连接密钥。 用户应用程序服务器通过 WebRTC 客户端对象 sapi.WebRtcClient.wskey 属性获取该密钥。

注解

  • 路径的第一部分 v0.1LinkRTC API 的版本,跨版本访问可能有兼容问题。
  • capi 表示客户端程序接口( Client Application Program Interface )。

举例

在浏览器上使用 JavaScript 建立 WebSocket 连接:

var projId = "your_project_sid";
var wsKey = "your_client_wskey";
var url = `wss://api.linkrtc.com/v0.1/capi/${projId}?key=${wsKey}`;
var wsRpc = new WebSocket(url);
/**
* RPC's response
*/
wsRpc.addEventListener('onmessage', (event) => {
    var data = JSON.parse(event.data);
    /// "id" is RPC's id
    id = data.id;
    /// "result" is RPC's returned result
    result = data.result;
});
wsRpc.addEventListener("readyState", (state) => {
    if (state == 0) {
        console.log("CONNECTING");
    } else if (state == 1) {
        console.log("OPEN");
        /**
        * Send JSON-RPC
        */
        wsRpc.send(JSON.stringify({
          jsonrpc: '2.0',
          id: 'Unique-RPC-ID',
          method: 'name_of_method',
          params: ['param0', 'param1', 'param2', 'param3'],
        }))
    } else if (state == 2) {
        console.log("CLOSING");
    } else if (state == 3) {
        console.log("CLOSED");
    }
});
内容

远程方法的调用和回复内容以 JSON 格式在 WebSocket 通道上传输, 具体内容请参考 JSON-RPC 2.0 标准。

定义

在下面的章节中,以函数定义的形式描述 JSON-RPC 的接口定义。

服务器提供的远程方法

发起出方向呼叫
capi.webrtcclient.make_call(sdp, from, to)
参数:
  • sdp (str) – 客户端的 SDP 字符串。
  • from (str) – 呼叫发起者,格式为 SIP URL。
  • to (str) – 呼叫接收者,格式为 SIP URL。
返回:

呼叫 ID,对应 sapi.Call.id 属性

返回类型:

str

举例

客户端调用:

{
    "jsonrpc": "2.0",
    "id": "2372",
    "method": "capi.webrtcclient.make_call",
    "params": {
        "sdp": "v=0\r\no=user2 1413 2673 IN IP4 192.168.100.105\r\ns=Talk\r\nc=IN IP4 192.168.100.105\r\nt=0 0\r\na=ice-pwd:37605d4ae30266e29a893f3f\r\na=ice-ufrag:55cf1b68\r\na=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics\r\nm=audio 7078 UDP/TLS/RTP/SAVPF 96 97 98 99 0 8 100 101 102 103\r\nc=IN IP4 119.32.243.210\r\na=rtpmap:96 opus/48000/2\r\na=fmtp:96 useinbandfec=1\r\na=rtpmap:97 SILK/16000\r\na=rtpmap:98 speex/16000\r\na=fmtp:98 vbr=on\r\na=rtpmap:99 speex/8000\r\na=fmtp:99 vbr=on\r\na=rtpmap:100 iLBC/8000\r\na=fmtp:100 mode=30\r\na=rtpmap:101 telephone-event/48000\r\na=rtpmap:102 telephone-event/16000\r\na=rtpmap:103 telephone-event/8000\r\na=setup:actpass\r\na=fingerprint:SHA-256 AC:4C:AA:6D:50:AF:CF:BA:31:4D:A0:22:50:DF:CA:E0:67:1B:D4:55:B2:1F:B9:7C:92:9F:DB:F6:78:90:53:AA\r\na=ssrc:4121415948 cname:sip:user2@sip.web2sip.hes86.net\r\na=candidate:1 1 UDP 2130706431 192.168.100.105 7078 typ host\r\na=candidate:1 2 UDP 2130706430 192.168.100.105 7079 typ host\r\na=candidate:2 1 UDP 1694498815 119.32.243.210 7078 typ srflx raddr 192.168.100.105 rport 7078\r\na=candidate:2 2 UDP 1694498814 119.32.243.210 7079 typ srflx raddr 192.168.100.105 rport 7079\r\na=rtcp-fb:* trr-int 5000",
        "from": "sip:40099998888@project1.sip.linkrtc.com",
        "to": "sip:13899922288@your_sip_provider.com"
    }
}

服务器回复:

{
    "jsonrpc": "2.0",
    "id": "2372",
    "result": "f3kjfee"
}
接受入方向呼叫
capi.webrtcclient.accept_call(call_id)
参数:call_id (str) – 要接受的呼叫 ID,对应 sapi.Call.id 属性
拒绝入方向呼叫
capi.webrtcclient.reject_call(call_id)
参数:call_id (str) – 要拒绝的呼叫 ID,对应 sapi.Call.id 属性
结束呼叫

由该客户端发起,或者交换到该客户端的任何呼叫,无论方向、状态,都被断开。

capi.webrtcclient.drop_call(call_id)
参数:call_id (str) – 要结束的呼叫 ID,对应 sapi.Call.id 属性

WebRTC 客户端远提供的程方法

呼叫状态变化通知
user.webrtcclient.on_call_state_changed(call)
参数:call (sapi.Call) – 状态变化后的 Call 对象。

注意

RPC 是通知性质的方法。如果服务器发送的调用数据中没有提供 id 属性,则客户端不必进行回复。

举例

服务器调用:

{
    "jsonrpc": "2.0",
    "method": "user.webrtcclient.on_call_state_changed",
    "params": [{
            "id": "f3kjfee",
            "dir": "outgoing",
            "prior_state": "pending",
            "curr_state": "calling",
            "...": "... ..."
    }]
}