上篇文章中我制作了很多灯,使用的mqtt协议
为了控制这些灯
我搭建了一台最简单的服务器
让我的灯可以连接上它
可以订阅消息 从服务器获得控制命令
可以发布消息 向服务器回传灯光状态
为了区分每盏灯
我给每盏灯起了不一样但设备名
分配不一样的安全密码
但灯连接服务器不容易使用ssl证书
所以我不能让灯使用明文密码来连接服务器
而是用密码经过单向加密产生的一个字符串作为连接鉴权字符串token
某些情况下token会保证服务器安全
因为我们不需要在服务器以外的地方暴露密码
控制端我依然用手机app来开发
但为了更方便app的多端开发
我的app尽量单靠h5那种开发模式来实现
app控制端尽量避免使用mqtt协议
最简单的办法就是在服务器上写接口api
写一个命令接口
当app需要给灯发命令时候
就调用接口向服务器接口发命令
接口携带上要控制的设备编号或是设备名
接口还携带上控制鉴权口令和控制目的字符串,比如off是关on是开
但控制鉴权不好搞,我不能每盏灯都要去存一个控制鉴权口令码
那开发起来太不方便来
所以我干脆给某些设备归属于某个产品
这个产品产生一个产品密码
我用这个产品密码单向加密换算成一个字符串
这个字符串就用来控制所有属于这个产品的设备
我的灯越来越多
为了控制它们的时候我的大脑和我的服务器都保持清醒
我必须考虑一套简单明了的控制逻辑
我给服务器和灯之间设定了一些规则
比如每盏灯只能订阅通过自己设备id换算出来的一个特定的命令主题来获得自己的控制命令
每盏灯也只能通过向使用自己设备id换算出来的一个特定的命令反馈主题来发布命令执行结果来反馈自己的状态
那样服务器上的设备管理更规范了
一盏灯也不能向其他主题发布乱七八糟的信息扰乱其他设备了
现在我的服务器成了这样
这样我的服务器基本功能就有了
但我的灯以后会越生产越多
我不能为每盏灯来操作服务器的数据库
登记每盏灯的名称和密钥
所以服务器给控制端的api中
我又加入了设备的增删api
那样我可以直接在手机上给服务器新增设备
我把新增设备的设备名、设备id、设备密钥换算出来的token
写到灯上的芯片中
每盏灯都可以被单独控制了
后来我的灯开始增加功能了
我的灯上面增加了温度传感器
我需要帮助灯的用户记录室内的温度变化
所以我又规定了
我的设备可以向通过自己设备id换算出来的一个特定的数据汇报主题发布数据
由于之前设计时候,控制端不是物联网的一部分
我只能把设备汇报的数据加上时间戳 记录在服务器中
为了访问这些数据
我又写了服务器的相应设备数据查询api
那样控制端可以查询指定设备在某段时间上传的数据了
![742f71020d17473564b0da66d5a77e8d.png](https://i-blog.csdnimg.cn/blog_migrate/cfbca43817d3ba124d850c9eda2549f0.jpeg)
现在我的灯已经可以登得上台面了
但还有个问题没有解决
我们的客户说
小张,我家停电了
你们的灯能不能在来电后
自动恢复成我最后在服务器上发布的指令状态呢
我给我的服务器上数据库中
记录设备的数据表又增加了两个字段
一个用来存储设备最后汇报的当前状态
另一个用来存储设备最后的目标状态
由于并不是所有客户都需要灯光能自动执行过时但未执行的指令
所以我又规定了两个新的mqtt主题
依然是设备根据自己的设备id换算出来的主题
一个主题给灯向服务器发布自己的当前状态
一个主题给灯订阅服务器最后给自己的目标状态
当客户需要灯光拥有自动同步服务器上记录的状态的能力时候
灯就使用这两种主题来和服务器通信
灯连接到服务器后
首先订阅服务器最后给自己的目标状态主题
然后向服务器发布自己当前的工作状态
服务器收到灯光状态汇报时
就分析灯当前的状态是不是和最后目标状态不一样
如果不一样,就给灯发布最后的目标状态
我同时给服务器增加了修改指定设备目标状态的api
这样一来,无论何时我只需要修改服务器上指定设备的目标状态数据库内容
对应设备如果订阅了自己目标状态主题并在第一时间向服务器发布当前状态
那么灯就会在最快的时间将自己的工作状态同步为服务器上的内容
就像服务器的影子
我管这种操作机制下的设备叫影子设备
也可以叫镜像设备,物理灯镜像了服务器的数据
当然,精力充足的我
还可以给服务器加上更多的操作逻辑
比如建立账号机制,不同的设备可以属于不同的账号
或是不同的产品属于不同的账号
设备向服务器发布某种内容时候
可以让服务器向所属账号发短信
让服务器可以给控制端推送消息
反正涉及物联网的部分,上面设备和服务器的mqtt连接,控制端和服务器的RESTful接口调用
也基本够用了
建这样的服务器太麻烦?
其实我只是分析了中国移动oneNet物联网服务器mqtt部分的设计逻辑
过段时间我再写BAT家的物联网服务器
先这样吧