1
xylophone21 2021-02-09 11:04:16 +08:00
参考 AWS 、阿里云的设备影子
另外涂鸦这个接口从哪里可以看出来是同步的? |
2
Vieufoux OP @xylophone21 谢谢,我的意思是这个接口发送请求之后就等待在哪里一直等到设备端的返回结果。我认为异步的实现是发送请求之后,服务器立刻返回一个 msgid,然后调用者再根据 msgid 去查询控制结果。
|
3
Slartibartfast 2021-02-09 11:10:10 +08:00 via iPhone
看文档确实是同步的,这样上层代码好写。
实际自己做底层逻辑的话,应该提供同步异步双接口 |
4
sxyclint 2021-02-09 11:27:58 +08:00
一楼说的没错,影子设备其实是比较好的实现,这样你接口设计成同步都没问题,反正就是修改影子的状态。
|
5
soulzz 2021-02-09 11:30:43 +08:00
底层 netty 写的话绝对是异步,然后用回调时用流水号或指令 id 做回调区分。
前台下发指令,后端会根据设备通讯协议下发字节流到设备,然后设置超时等待。 收到设备回复的接收到指令的消息回复,新建一个 Future 实例并缓存,然后等待设备的执行结果回调,收到执行结果的时候将 Future 实例移除,并对取出的 Future 进行设值。 在超时等待时间段内如果有回调就返回执行结果,没有就返回超时或者失败。 这样对前端或者第三方指令接入友好。 当然,如果是用 websocket 写的接口就不用这么麻烦,约定好回复结构,实时返回指令下发与接收过程的每一步 |
6
swulling 2021-02-09 11:40:07 +08:00 4
一般这种非立刻生效但是耗时预估也不会太久(<10s )的接口,有三种实现模式
同步接口:优点是上层业务逻辑简单,缺点调用耗时较长,接口并发性能较差。 而且偶尔超时后就比较麻烦,有可能状态不一致。比如下发的动作执行了,但是返回时超时。 异步接口:优点是实现简单,还可以利用消息队列等方式来提升性能,理论上接口不会成为性能瓶颈。缺点是上层的业务开发比较复杂,需要自己实现轮询状态或者用长链接监听状态。 声明式接口:上层只需要下发期望,比如下发灯亮这个期望,设备定时去往这个期望变化。这种就类似于 Kubernetes 的接口,优点是能够保证最终一致性,缺点是还需要配合查询接口来轮询或者长链接 Poll 的方式看下当前状态是否达到期望。 目前从开发习惯上,还是同步或者异步接口比较多,但是复杂控制系统声明式接口有它非常大的优势。 |
7
swulling 2021-02-09 11:41:08 +08:00
上面说的影子设备、Future 实例等,都是声明式接口的一种变种。
|
8
Vieufoux OP @xylophone21 @xylophone21 谢谢,设备影子确实可以做到立刻返回
|
9
Vieufoux OP @swulling 谢谢,我之前就是实现了同步接口,确实会有一些临界 case 导致设备端执行成功但是 HTTP 请求显示超时了。后来又尝试了异步接口,客户端轮询,这种方式上层实现麻烦而且不能保证实时性。
|
10
laminux29 2021-02-09 12:37:49 +08:00
科学的方式,是把整个业务进行过程式细化,然后接口设计为异步,并且提供过程状态查询接口。
比如: 用户通过 http 请求发送到指令到后台后,就不需等待,只需要调用过程状态查询接口,来查询目前后台处理状态。处理状态有且不限于: 1.查询不到请求。也就是用户 http 请求可能根本没发送到后台。 2.后台已经收到请求,后台正在向设备端下发指令。 3.后台在向设备端下发指令时出错,错误信息是:..... 4.设备端已经收到指令,等待设备端处理。 5.设备端处理超时。 6.设备端处理时发生错误,错误信息是:...... 7.设备端已经处理完毕,目前设备端的状态是:...... 这种设计,缺点是工作量比较大,优点是科学、严谨、用户体验好。 |
11
xylophone21 2021-02-09 14:14:45 +08:00
这里楼主给的链接里关于返回参数的说明
返回参数 参数名 类型 说明 code Integer 错误码。 success Boolean 判断请求是否成功。 true:成功 false:失败 msg String 请求失败返回的信息,成功则返回空值。 result Boolean 是否成功。 返回的信息里只有是否成功,并没有说这个成功是执行还是请求还是修改影子,当然这是文档的问题。 但一般情况下这个场景不需要同步接口,因为下行通道是必须的,否则如果其它控制渠道(比如物理面板,物理遥控器)的控制就没办法反馈了。 |
12
tienhua 2021-02-09 14:27:17 +08:00 via iPhone
我的经验是采用 grpc 的 bidi stream 方案
|
13
BingoXuan 2021-02-09 16:08:35 +08:00 via Android
异步,mqtt 本身就是通过队列控制 iot 的状态,HTTP 只是查询。HTTP 更新 iot 状态,设备获取最新订阅消息然后执行,无论成功与否,更新最新状态,在最新状态更新之前,HTTP 都能及时获取最后设备更新的状态。
|
15
Vieufoux OP @BingoXuan 谢谢,我理解这种实现就是设备影子,但是怎么能知道设备状态是否真的更新成功了?
|
16
janxin 2021-02-09 19:32:13 +08:00
底层肯定是异步啊...
|
17
noroot 2021-02-09 19:40:17 +08:00
你说的应该是后台通过 MQTT 发指令到网关,网关处理这些指令并转发相关消息到终端网络吧。
这个接口大概只是客户端同步等待,服务器自身异步处理(简单的方法可以是将你的请求注册到相应的 MQTT 主题下)。 |
18
micean 2021-02-09 20:31:34 +08:00 via Android
页面设备状态的刷新避免不了长连接或者轮询请求
|