对于iot 来说,设备上的上下线事件非常关键并重要,怎对事件的监听呢?
在mqtt协议中,存在LTW(Last Will and Testament)遗言机制,该机制只能捕捉客户端异常离线的通知,而无法获取正常通过disconnect断开连接的通知。
LTW(Last Will and Testament)遗言机制
客户端在连接到Mqtt服务器时,需指定will topic和will message遗言信息,
之后若在客户端异常断开(弱网络、服务被终止,而非正常disconnet)时会由mqtt服务器主动向will topic发送will message,
此时其他监听will topic的用户即可获得客户端离线的will遗言通知;
而在Emqx,存在系统主题订阅,其中的系统主题
上线通知:
$SYS/brokers/${node}/clients/${clientId}/connected
下线通知
$SYS/brokers/${node}/clients/${clientId}/disconnected
LWT和Emqx SYS主题通知效果对比:
机制\事件 | connect | disconnect | 异常disconnect |
$SYS/brokers/${node}/clients/${clientId}/connected | ✔ | | |
$SYS/brokers/${node}/clients/${clientId}/disconnected | | ✔ | ✔ |
LWT | | | ✔ |
通过实际测试对比发现,LWT仅支持异常disconnect的通知,而emqx的$SYS/brokers/${node}/clients/${clientId}/disconnected系统主题可以捕捉到所有离线通知(主动diconnect、异常disconnect),即emqx的系统主题即可完整支持客户端上线、下线监听的需求。可以根据实际的需求选择适当的机制。
emqx中使用上下线事件:
connected
事件消息的 Payload 解析成 JSON 格式如下:
disconnected
事件消息的 Payload 解析成 JSON 格式如下:
当然在开发的时候我们订阅两个主题比较麻烦,在这里我们可以采用主题通配符模式直接订阅一个主题即可:
$SYS/brokers/+/clients/#
内置 ACL设置:
内置 ACL 通过文件设置规则,使用上足够简单轻量,适用于规则数量可预测、无变动需求或变动较小的项目。
ACL 规则文件:
内置 ACL 优先级最低,可以被 ACL 插件覆盖,如需禁用全部注释即可。规则文件更改后需重启 EMQ X 以应用生效。
定义 ACL:
内置 ACL 是优先级最低规则表,在所有的 ACL 检查完成后,如果仍然未命中则检查默认的 ACL 规则。
该规则文件以 Erlang 语法的格式进行描述:
- 第一条规则允许客户端发布订阅所有主题
- 第二条规则禁止全部客户端订阅
$SYS/#
与 #
主题 - 第三条规则允许 ip 地址为
127.0.0.1
的客户端发布/订阅 $SYS/#
与 #
主题,为第二条开了特例 - 第四条规则允许用户名为
dashboard
的客户端订阅 $SYS/#
主题,为第二条开了特例
可知,默认的 ACL 主要是为了限制客户端对系统主题 $SYS/#
和全通配主题 #
的权限。
如果想监听系统主题上下线,需要如下配置:
重新加载acl文件(或者重启emqx服务)
当然在开发的时候我们订阅两个主题比较麻烦,在这里我们可以采用主题通配符模式直接订阅一个主题即可:
$SYS/brokers/+/clients/#
这样比较方便,只不过需要我们在回调函数中进行Topic主题的区分就可以了,例如: