复杂度及效率评估
- 物联网应用维护复杂度 x 0.01
-
这里对比基于RTIO和MQTT开发的物联网应用,主要面向远程控制场景,其复维护及版本迭代等杂度。
定义物联网应用关键因素:
- N1为用户端应用(APP)共存版本数量
- N2物联网设备端(Device)OTA版本数量
- 通常一款APP支持多种物联网设备,N3为物联网设备类型数量
- N4设备数量级(10^N)
等效公式:有耦合相乘,非耦合相加。MQTT通常会定义一对
*_Req
和*_Resp
主题(Topic),发布订阅为不同端,存在耦合1。RTIO资源以URI形式描述,比如设备端增加v1/v2等版本不会耦合到用户端。- MQTT复杂度=N1xN2xN3xN4=O(N^4)
- RTIO复杂度=(N1+N2+N3)xN4=O(N^2)
为了直观展示,这里N用10表示,其复杂度为传统基于MQTT的百分之一2。
- 物联网应用开发速度 x 10
-
这里对比基于RTIO和MQTT物联网应用开发速度,主要面向远程控制场景。
- C语言的物联网设备端Demo,RTIO代码量只有AWS MQTT Demo的十分之一(122行 vs 1500+行)3。RTIO关键代码只有几行。
- 用户端(移动/PC/WEB端)可直接使用HTTP与RTIO服务通信,无需集成SDK。
- 使用RTIO相比MQTT各端交互量交互减少一般以上1。
- 可使用curl等HTTP工具对设备接口透过RTIO服务进行验证,解耦各端调试。
- 通常RTIO直接与物联网应用服务部署在一个局域网内,不需要过多认证,接口简单高效。
- RTIO专注物联网远程通信,功能更简单,使用门槛低,相比AWS-IoT-Core上百个文档4,RTIO不超10个文档。
综上原因,评估RTIO物联网开发速度提升10倍5。
关于RTIO
- 为什么创建RTIO?
-
面向点对点远程通信,简化IoT应用开发。
物联网设备与RTIO服务端通信类似MQTT,底层基于TCP长连接,云端可向设备推送消息,旨在避免MQTT(发布订阅模型)应用于点对点远程通信带来的复杂性。并融合以下想法:
- 一次调用返回设备执行结果或超时。
- 解耦设备、设备调用端(比如移动端)和应用服务端之间的实现,三端可以自行维护各自版本。
- 设备也是服务资源的提供者,使设备端开发具有和WEB服务开发相似的体验和高效。
- 弥合移动端、服务端和嵌入式开技术鸿沟,各端采取各自技术栈,最终实现物联网应用。
- RTIO如何实现
-
- 调用端(比如移动端)直接使用HTTP与RTIO服务通信,发起设备调用,无需集成SDK。可使用
curl
/postman
等工具对设备能力进行验证。 - 以URI标识不同资源或能力,比如设备提供
/printer/action
、/printer/action/v2
接口,方便设备能力分类和迭代。 - 面向点对点远程通信,一次通信可承载请求数据和响应数据,相比MQTT减少一半以上交互。
- 提供易于移植的设备SDK,设备端将
处理函数
(handler)注册到对应URI
即可。
- 调用端(比如移动端)直接使用HTTP与RTIO服务通信,发起设备调用,无需集成SDK。可使用
- 什么场景选择点对点通信,U2M(User To Machine)选择哪种模型更合适?
-
“点对点通信”为两台设备间通信,“多对多通信”即多台设备间通信。
U2M为用户端(比如手机)控制物联网设备,是典型的点对点通信。如果采用发布订阅作为通信模型,也可实现对IoT设备控制。但相比点对点通信会复杂许多1。
另外,一个用户控制多台物联网设备,点对点通信是否适用?如果物联网设备间不进行复杂的交互,仅增加批量的控制逻辑即可,该场景点对点模型仍比发布订阅模型交互简单。
用户端可通过RTIO代理服务实现“点对点远程通信”,比如手机和物联网设备可以不在一个局域网内。
与MQTT交互比较
- 控制物联网设备
-
面向对点对点远程控制场景,比较RTIO和MQTT交互过程,可点击展开。
用户通过移动端APP控制开关, RTIO交互
+--------+ +------------+ +--------+ | app | | rtio | | device | +--------+ +------------+ +--------+ | | | | user power on | | |-----+ | | | | | | |<----+ | | | | | | HTTP-POST | | | $diviceid/led_power | | |-------------------->| | | | | | | CoPOST /led_power | | |--------------------->| | | | | | |-----+ | | led power action | | | | |<----+ | | led_power status | | |<---------------------| | | | | led_power status | | |<--------------------| | | | | +--------+ +------------+ +--------+ | app | | rtio | | device | +--------+ +------------+ +--------+
用户通过移动端APP控制开关, MQTT交互
+--------+ +------------+ +--------+ | app | | broker | | device | +--------+ +------------+ +--------+ | | | | | SUBSCRIBE | | | $diviceid_led_power_req | |<---------------------| | | SUBACK | | |--------------------->| | SUBSCRIBE | | | $diviceid_led_power_resp | |-------------------->| | | SUBACK | | |<--------------------| | | | | | | | | user power on | | |-----+ | | | | | | |<----+ | | | | | | PUBLISH | | | $diviceid_led_power_req | |-------------------->| | | PUBACK | | |<--------------------| | (PUBACK:means brocker successfully received not device) | | | | | PUBLISH | | | $diviceid_led_power_req | |--------------------->| | | PUBACK | | |<---------------------| | | |-----+ | | led power action | | | | |<----+ | | | | | PUBLISH | | | $diviceid_led_power_resp | |<---------------------| | | PUBACK | | |--------------------->| | | | | PUBLISH | | | $diviceid_led_power_resp | |<--------------------| | | PUBACK | | |-------------------->| | | | | +--------+ +------------+ +--------+ | app | | broker | | device | +--------+ +------------+ +--------+
得出以下结论:
- 第一幅图基于RTIO,各端间交互4次。
- 第二幅图基于MQTT,各端间交互12次。
假设新版本增加
led_power_b
功能。- 如果使用RTIO在设备端注册
led_power_b
URI和处理函数即可。 当新版应用端调用旧版设备端时,因旧版设备没有led_power_b
URI,会立即返回资源不存在
错误(可根据实际情况提示用户升级设备)。 - 如果使用MQTT,首先设备端需订阅
led_power_b_req
,应用端需订阅led_power_b_resp
,这两个主题耦合在于两端。当新版应用端调用旧版设备端时,因旧版设备没订阅led_power_b_req
主题,也不会向led_power_b_resp
发布消息,相当于没有响应,通常需要设备端一起升级。
- 物联网设备向云端请求
-
参考以下交互图,可点击展开。
请求version列表, RTIO交互
+--------+ +------------+ +----------+ | device | | rtio | |app-server| +--------+ +------------+ +----------+ | | | | auto discover resource and registry | | |-----+ | | | | | | |<----+ | | | | | CoPOST | | | /resource/versions | | |-------------------->| | | | HTTP-POST | | | /resource/versions | | |--------------------->| | | | | | |-----+ | | query versioins | | | | |<----+ | | versions | | |<---------------------| | | | |versions | | |<--------------------| | | | | +--------+ +------------+ +----------+ | device | | rtio | |app-server| +--------+ +------------+ +----------+
请求version列表, MQTT交互
+--------+ +------------+ +----------+ | device | | broker | |app-server| +--------+ +------------+ +----------+ | | | | | SUBSCRIBE | | | $deviceid_get_versions_req | |<---------------------| | | SUBACK | | |--------------------->| | SUBSCRIBE | | | $deviceid_get_versions_resp | |-------------------->| | | SUBACK | | |<--------------------| | | | | | | | | PUBLISH | | | $deviceid_get_versions_req | |-------------------->| | | PUBACK | | |<--------------------| | | | | | | PUBLISH | | | $deviceid_get_versions_req | |--------------------->| | | PUBACK | | |<---------------------| | | |-----+ | | query versioins | | | | |<----+ | | | | | PUBLISH | | | $deviceid_get_versions_resp | |<---------------------| | | PUBACK | | |--------------------->| | | | | PUBLISH | | | $deviceid_get_versions_resp | |<--------------------| | | PUBACK | | |-------------------->| | | | | +--------+ +------------+ +----------+ | device | | broker | |app-server| +--------+ +------------+ +----------+
同样得出以下结论:
- 第一幅图基于RTIO,各端间交互4次。
- 第二幅图基于MQTT,各端间交互12次。
- 观察者模式
-
参考以下交互图,可点击展开。
用户通过移动端“观察”设备处理进度, RTIO交互
+--------+ +------------+ +--------+ | app | | rtio | | device | +--------+ +------------+ +--------+ | | | | | | | HTTP-GET | | | $diviceid/progress | | |-------------------->| | | | | | | ObGET /progress | | |--------------------->| | | 20% | | |<---------------------| | 20% | | |<--------------------| | | | 30% | | |<---------------------| | 30% | | |<--------------------| | | | | (The observation can be terminated by device or app) | | | | | TERMINAT | | |<---------------------| | TERMINAT | | |<--------------------| | | | | +--------+ +------------+ +--------+ | app | | rtio | | device | +--------+ +------------+ +--------+
观察模式类似MQTT消息订阅,但更为灵活,可以随时发起观察和取消。调用端仍然使用HTTP协议,无需额外操作,比如订阅。
MQTT没有该模式。
与MQTT比较总结
- 比较总结
-
MQTT为轻量高效的通信协议,适合受限设备,RTIO通信协议设计过程也有参考MQTT协议。以下是二者对比的总结。
- MQTT为发布订阅模型,更适合多对多通信。
- RTIO为点对点通信模型,更适合比如手机控制设备等远程控制场景。以下为具体比较。
特点 MQTT RTIO 通信模型 发布订阅模型 点对点,REST-Like模型6,支持观察模式7 调用端集成SDK 需要 不需要,使用HTTP协议 远程控制实现难度 复杂 简单8 协议轻量高效 是 是9 双向通信 是 是 百万连接 支持 支持 可靠消息传输 支持 支持10 不可靠网络 支持 支持11 安全通信(TLS) 支持 支持 JWT验证 - 支持12
-
非严谨模型,目的表达RTIO可降低物联网应用维护复杂度,仅供参考。 ↩︎
-
参考:aws-iot-device-sdk-embedded-C 项目的 mqtt_demo_basic_tls.c。 ↩︎
-
参考:what-is-aws-iot页面。 ↩︎
-
非严谨模型,目的说明RTIO提升物联网应用开发速度,仅供参考。 ↩︎
-
REST-Like这里指类似RESTful模型,提供了
CoPOST
(Constrained-Post,类似HTTP-POST)方法和ObGET
(Observe-GET,观察模式)方法,通过URI
标识资源或能力。 ↩︎ -
观察模式类似MQTT消息订阅,但更为灵活,可以随时观察和取消。调用端仍然使用HTTP协议,无需额外操作(比如
订阅
)。 ↩︎ -
RTIO相对MQTT无需
订阅
、发布
等流程。远程控制设备等点对点通信场景下,比MQTT实现交互次数减少一半以上,且无Topic耦合,参考: 与MQTT交互比较 章节。 ↩︎ -
可运行于几十KB至百KB RAM的设备。协议轻量,URI传输时采用经HASH「压缩」后的URI,仅4字节,通信效率更高。 ↩︎
-
RTIO没有QOS,可靠性依赖TCP,当时限内无法传达消息会直接向调用者报错。 ↩︎
-
RTIO物联网设备端SDK断网后自动重连。 ↩︎
-
HTTP调用端支持JWT验证,带有合法的JWT的请求才能请求RTIO服务,对设备发起调用。 ↩︎