连接MQTT服务器
对接流程:先对接阿里云MQTT,后对接华为云emq,具体对接方式如下
一、连接阿里云MQTT服务器
获取MQTT令牌并连接MQTT服务器
HttpPost接口地址 SERVICE-ADDRESS/model/getMqttTokenInfo/v2
header头部参数说明
参数 | 类型 | 是否必须 | 说明 |
---|---|---|---|
appid | String | 是 | 唯一凭证 |
sign | String | 是 | 签名 |
ts | Long | 是 | 系统当前毫秒数 |
body参数说明
参数 | 类型 | 是否必须 | 说明 |
---|---|---|---|
deviceCode | String | 是 | 设备编码 |
action | String | 是 | 申请的token权限类型(R:读权限 W:写权限 RW:读写权限),一般为W |
refresh | Boolean | 是 | 是否强制刷新token [true or false] 如果为true,则获取一个新的token,否则尝试读取缓存 |
返回数据示例
{
"message": "string",
"success": true,
"code": "string",
"data": [
{
"action": "W",
"expireTime": 1613617209000,
"token": "LzMT+XLFl5uQ6bDU0o4vUinNvsVrLa8SwZDePNpP0o5YfYNDKkKbsA/lDnhfVjgSTLyohRU9uIz3Tdh9/Denf0tjquO1yEJnvoH7TR5+i7nBtbqyhUl481lyKJ1mZo6Sv0Hq5RYJa2J9GZpMwgNlT3GLaGZf2t87zyxtwiOrr239OWaTIjFxmPIR29DjJuMAVGj2HJ4FkwHCKS5L/oYyacAFYbtu0qAx+vt+Pkz5ZriC/8cH8QMwaD5urrwXrSx3KgrxXZfNgyJkRwdpUfmWFu9g81nI1POh" //token
}
]
}
action
token权限(R:读权限 W:写权限 RW:读写权限)
token
令牌信息,String
expireTime
token到期时间戳(13位),Long,在该时间此令牌会过期,请在开启定时任务,并此时间戳前条用此方法刷新token
使用token模式认证方式链接MQTT服务
连接信息
-
aliBaseInfo,huWeiBaseInfo 两种结构只会返回一个,返回为
aliBaseInfo
连接阿里云所在的MQTT服务 -
aliBaseInfo使用token模式认证授权链接MQTT,mqttTokenExpire为token过期时间
-
【订阅的topic地址】 = 【返回信息中topic】 + 【返回信息中sub】
-
【MQTT 服务器地址serverUri】 = 【"tcp://"】+ 【endPoint】+【"tcpPort"】
- token 只能从广联达的服务端获取,获取后设备端拿到新的token,告诉 mqtt 服务器,我即将用这个新的 token和你通信
完整的链接信息例子如:
-
注意此图中为列出
sub
信息, 途中代码的topic
字段 "GLM" 为根topic
, 任何人无权订阅发布,设备端需要按照【订阅的topic地址】的拼接规则,拼接处设备端通讯的topic
, 假如:接口信息返回sub
为 "gateface/e/1", 那么服务端通信的 “topic” 为 "GLM/gateface/e/1" 客户端往这里发送信息即可 -
特别提示:topic 信息和token以及权限信息要从服务端动态读取请勿在本地硬编码
-
特别提示:客户端MQTT服务启动的时候不要显示的订阅任何 topic, 阿里云服务会自动帮设备端订阅P2P的通信topic,客户端只要处理 “messageArrived()” 方法回调即可,不熟悉的开发人员可能会订阅
GLM
根 topic导致自己无法正常收发信息
更多P2P信息请参考:https://help.aliyun.com/document_detail/96176.html?spm=a2c4g.11186623.6.553.7d054de4ebdo2l
- 上述
GLM
为测试环境根topic,这里为了好表述所以直接呈现给大家,这个需要从 iot init 接口中动态获取,测试环境和正式环境不一样,后续假如迁移升级客户端无需做任何修改
连接参数拼接
连接类型默认一般为W
,需要从前一篇init
接口中的 mqttTokens
字段中读取
Token 模式下 MQTT 客户端的连接参数设置如下。
-
ClientId 连接阿里云mqtt时的客户端的
ClientId
是由 :动态参数
groupId
(从init接口动态获取)+固定字符@@@
+动态参数劳务平台的设备号
三部分拼接而来比如:GID_GLM@@@GLODON0001(
GID_GLM@@@
是阿里云规定的前缀,GLODON0001是该设备在劳务平台的设备号) -
Username 由鉴权模式名称固定字符
Token
、动态参数AccessKeyId
、动态参数InstanceId
三部分组成,以 “|” 分隔。Token 模式下鉴权模式设置为”Token”。举例:使用了实例 ID 是 xxxxx,使用了 AccessKeyId 是 YYYYY,则 Token 模式的 UserName 应该设置成 “Token|YYYYY|xxxxx”。
特别提示:ClientId的这种拼接格式仅仅在连接阿里云时会用到,
后面调用接口上报数据时涉及到的clientId不用携带GID_GLM@@@部分,
请直接传递劳务平台的设备号也即:GLODON0001
-
Password: 具体设置方法是将所有的 Token 按照 Token 类型和 Token 内容依次使用“|”连接符拼接成一个完整的字符串,不同类型之间的 Token 拼接顺序无要求。
一般情况下Token 模式的 Password 应该设置成:
W|{服务端请求返回的Token字段}
,请关注服务端反馈的token信息
Token认证的更多信息: https://help.aliyun.com/document_detail/54282.html?spm=a2c4g.11186623.6.577.22434971RXlpZ4
Token更新
根据服务端mqttTokens数组返回的expireTime
字段计算过期时间提前刷新
设备方拿到token自己计算过期时间,开启任务定时刷新,定时去劳务平台申请新的token,然后调用阿里云的刷新Token的方法,发送Token到Topic:"$SYS/uploadToken",动态完成token的刷新,设备无须重新连接
此外,Token过期前5分钟左右设备端会收到如下信息,消息通过P2P通道发送给设备,请注意监听messageArrived
方法并接受阿里云过期提醒的消息:
topic=$SYS/tokenInvalidNotice, message={"cdode":2,"type":"W"}
此时证明token即将过期需要更换,需要客户端立刻调用刷新token接口并更新到阿里云,该 Token 即将于什么时候失效,格式为毫秒时间戳,一般提前 5 分钟通知,只通知一次,但服务端不保证一定会有通知。
也就是刷新两种方式 : 1. 根据expireTime 自己做定时主动刷新,这是主要方式 2. 收到阿里云过期通知立刻刷新这是补充
请注意: 发送消息时假如提示token过期,此时MQTT也会断开,此时需要去劳务平台申请Token并重新连接MQTT服务
请留意token过期时间和过期提示消息
更多信息请参考:https://help.aliyun.com/document_detail/54282.html?spm=a2c4g.11186623.6.575.13fa49478qrjpY
二、连接华为云EMQ服务器
连接信息
-
当设备通过华为云接入时使用
huWeiBaseInfo
-
huWeiBaseInfo为华为云对接认证方式为账号密码认证
-
【订阅的topic地址】 = 【返回信息中topic】
-
【emq 服务器地址serverUri】 = 【"tcp://"】+ 【endPoint】+【"tcpPort"】
连接参数
emq连接与mqtt存在4点差异,具体如下:
* ClientId
连接emqx时的客户端的ClientId
: 直接使用设备号
比如:GLODON20200107001 (GLODON20200107001是该设备在劳务平台的设备号)
-
Username 平台所提供的第三方编码appId
-
Password: 平台所提供的第三方秘钥secret
主动订阅
EMQ连接需要主动订阅topic来接收p2p消息
在连接建立后主动订阅 GLM/p2p/DEVICE_CODE
, DEVICE_CODE 是自己的设备号,订阅完此队列后,同样在 messageArrived
处理回调逻辑即可
常见问题
- 连接emq服务器,返回Connection refused:Not authorized错误信息字样时,联系广联达劳务对接人。