Skip to content

连接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和你通信

完整的链接信息例子如:

image

  • 注意此图中为列出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错误信息字样时,联系广联达劳务对接人。