TVS 通过 HTTP/2 长连接向客户端下发由云端发起的指令,比如闹钟、媒体播放控制等。本章将介绍如何创建和维护与 TVS 之间的 HTTP/2 连接。
注意:
设备在同一个连接内应当只建立一条下行通道。
设备和 TVS 建立 HTTP/2 连接,必须先通过 TVS 的 登录授权 获得 Access Token。
所有请求头都应当包含 Access Token,类似于:
:method = POST :scheme = https :path = /tvs/events authorization = Bearer {YOUR_ACCESS_TOKEN} content-type = multipart/form-data; boundary={BOUNDARY_TERM}
测试环境域名: test-h2.g-aicloud.alibaba.com
提测环境域名: test2-h2.g-aicloud.alibaba.com
协议:https
端口:443
设备开机后应当和 TVS 建立 单条 HTTP/2 连接。该连接用于处理所有指令和事件,包括通过下行通道流向设备推送的所有指令。
与 TVS 维持连接的要求:
1、创建下行通道流,设备需要在连接开启后的 10 秒内向 /tvs/directives
发出一个 GET
请求,类似这样:
:method = GET :scheme = https :path = /tvs/directives?requestId=xxx authorization = Bearer {YOUR_ACCESS_TOKEN}
其中,url参数requestId
表示请求id,用于标识此次下行通道创建请求,客户端需要生成一个32位的随机字符串(小写字母+数字),并尽量保证唯一,例如:6cd8a3539f174ac098089b0f5d56f149。
如果请求成功,这个连接会维持在半开状态。
2、下行通道建立成功之后,设备应当向 TVS 同步自己的组件状态。实现方式是在现有的连接中( 注意: 不要开新连接)发起一个新的事件流向 /tvs/events
发出一个 POST
请求。该事件流应当在收到响应之后关闭。下面是一个 SynchronizeState
事件的例子:
:method = POST :scheme = https :path = /tvs/events authorization = Bearer {YOUR_ACCESS_TOKEN} content-type = multipart/form-data; boundary={BOUNDARY_TERM_HERE} --{BOUNDARY_TERM_HERE} Content-Disposition: form-data; name="metadata" Content-Type: application/json; charset=UTF-8 { "context": [ // 上下文对象的数组,用于告知 TVS 设备端所有组件的状态。 ], "event": { "header": { "namespace": "System", "name": "SynchronizeState", "messageId": "{STRING}" }, "payload": { } } } --{BOUNDARY_TERM_HERE}--
状态同步之后,设备即可利用这个连接处理以下事情:
注意:
每个事件和它的响应都在自己独立的事件流中发送;响应接收完毕之后应该将流关闭。
一旦连接建立,设备需要知道如何管理事件流、下行通道流、心跳、超时和云端发起的断开。
建议使用 10ms、320 字节分片(每次发送 320 字节的 DATA 帧)、流式地向 TVS 传输捕获到的音频。过大的分片可能会导致不必要的缓冲,导致延迟增加。
向 TVS 发送的音频编码:
16bit 线性 PCM(LPCM16)
详见语音识别接口。
单个 HTTP/2 连接仅支持 10 个并发的流,包括事件流、下行通道和心跳。再次提醒,事件流收到响应之后应该关闭。
大多数请求库对读取时间可能会有超时机制。由于 TVS 的下行通道流是一个长连接,在相当长一段时间内即便没有指令下发也应当维持开启状态。因此需要将读取超时设置为至少 60 分钟。
每一个事件都使用自己独立的流发送。通常情况下一条流会在当 TVS 返回指令和对应的音频附件之后关闭。
请求应该是顺序处理的。也就是说,应该在 TVS 开始响应上一个请求(设备收到了响应头)之后才发出新的请求。
Play
或 Speak
指令里 cid:
开头的 url 对应音频附件里的头。注意:
设备可能会收到多个指令(JSON)之后才收到对应的音频附件。因此,设备应当能够关联指令和它对应的音频附件。
一些指令也可能会并行于事件流地从下行通道发送到设备。下行通道通常用于接收云端发起的指令。
GET
请求。设备应该采取下列其中一个措施来维持连接,遇到失败后需要关闭连接并重试。
PING
帧/tvs/ping
接口发出一个 GET
请求示例:
:method = GET :scheme = https :path = /tvs/ping authorization = Bearer {YOUR_ACCESS_TOKEN}
一旦 PING 失败,设备应当关闭当前连接,并立刻重新创建一个新的连接。
注意:
如果使用 libcurl,设备需要每 5 分钟向
/tvs/ping
发一次GET
来维持连接。
当服务器主动断开了连接,设备应该:
如果重新连接失败,设备应该采取适当的间隔重试机制。