快速使用MQTT.fx模拟SDK收发消息

更新时间:
复制 MD 格式

MQTT.fx是一款基于Eclipse Paho、使用Java语言编写的MQTT客户端。支持Windows、Mac和Linux操作系统,可用于验证设备是否可以连接云消息队列 MQTT 版,并通过Topic发布和订阅消息。本文以Windows系统为例,介绍如何使用MQTT.fx模拟SDK接入云消息队列 MQTT 版并进行消息收发。

前提条件

下载并安装MQTT.fx。

背景信息

云消息队列 MQTT 版最简单的使用场景即MQTT客户端消息的自发自收。如下图所示,您可以使用MQTT.fx作为MQTT客户端,在MQTT.fx客户端配置相关参数后接入云消息队列 MQTT 版实现消息的发送和接收。消息收发

云消息队列 MQTT 版同时提供了公网接入点和VPC 接入点。

  • 在物联网和移动互联网的场景中,客户端推荐使用公网接入点接入。

  • VPC 接入点仅供一些特殊场景使用。例如涉及部署在云端服务器上的应用场景。

本示例以公网接入点为例接入云消息队列 MQTT 版。

使用流程

使用MQTT.fx收发消息的流程如下图所示。操作流程

(RAM用户必选)步骤一:为RAM用户授权

若您开通消息队列服务使用的是账号是RAM用户,必须先为RAM用户进行授权,才能访问云消息队列 MQTT 版的资源。若您的账号是阿里云账号,默认拥有使用云消息队列 MQTT 版资源的权限,您可以跳过该步骤。

  1. 使用RAM管理员登录RAM控制台。

  2. 在左侧导航栏,选择身份管理 > 用户。

  3. 在用户页面,单击目标RAM用户操作列的添加权限。

    您也可以选中多个RAM用户,单击用户列表下方的添加权限,为RAM用户批量授权。

  4. 在新增授权面板,为RAM用户添加权限。

    1. 选择资源范围。

    2. 选择授权主体。

      授权主体即需要添加权限的RAM用户。系统会自动选择当前的RAM用户。

    3. 选择权限策略。

      权限策略是一组访问权限的集合,分为以下两种。支持批量选中多条权限策略。

      • 系统策略:由阿里云创建,策略的版本更新由阿里云维护,用户只能使用不能修改。更多信息,请参见支持RAM的云服务。

        说明

        系统会自动标识出高风险系统策略(例如:AdministratorAccess、AliyunRAMFullAccess等),授权时,尽量避免授予不必要的高风险权限策略。

      • 自定义策略:由用户管理,策略的版本更新由用户维护。用户可以自主创建、更新和删除自定义策略。更多信息,请参见创建自定义权限策略。

    4. 单击确认新增授权。

  5. 单击关闭。

云消息队列 MQTT 版提供以下系统策略,您可以根据权限范围为RAM用户授予相关权限。

权限策略名称

说明

AliyunMQFullAccess

管理云消息队列 MQTT 版的权限,等同于阿里云账号的权限,被授予该权限的RAM用户具有所有消息收发权限且有控制台所有功能操作权限。

AliyunMQPubOnlyAccess

云消息队列 MQTT 版的发布权限,被授予该权限的RAM用户具有使用阿里云账号所有资源通过SDK发送消息的权限。

AliyunMQSubOnlyAccess

云消息队列 MQTT 版的订阅权限,被授予该权限的RAM用户具有使用阿里云账号所有资源通过SDK订阅消息的权限。

AliyunMQReadOnlyAccess

云消息队列 MQTT 版的只读权限,被授予该权限的RAM用户仅有通过访问控制台或调用管控API读取资源信息的权限。

步骤二:创建MQTT实例并获取接入点

  1. 登录云消息队列 MQTT 版控制台。
  2. 在左侧导航栏单击实例列表。
  3. 在顶部菜单栏选择地域。
  4. 在实例列表页面左上角单击创建实例。
  5. 在弹出的付费方式面板中,选择按需选择包年包月或Serverless 按量付费,然后单击确定。

  6. 在弹出的商品购买页中,选择实例类型和各计费项的规格,然后单击立即购买。

    云消息队列 MQTT 版支持的实例类型及功能差异,请参见实例类型。

  7. 在确认订单页面,根据提示完成支付。

  8. 在支付成功页面单击返回控制台。
  9. 回到云消息队列 MQTT 版控制台,在左侧导航栏单击实例列表,并将地域切换为您所购买的实例所对应的地域。
  10. 在实例列表页面中,单击您所购买实例的名称或在其操作列单击详情,进入实例详情页面。
  11. 在实例详情页面单击接入点页签,即可看到实例的接入点信息,本示例以公网接入点为例。
    接入点

步骤三:创建父级Topic

MQTT协议支持多级Topic,父级Topic需在控制台创建,子级Topic无需创建,使用时直接在代码中设置即可。命名格式为:父级Topic和各子级Topic间均使用正斜线(/)隔开,<父级Topic名称>/<二级Topic名称>/<三级Topic名称>,例如,SendMessage/demo/producer。父级Topic和子级Topic总长度不能超过64个字符。Topic详细信息,请参见名词解释。

  1. 登录云消息队列 MQTT 版控制台,并在左侧导航栏单击实例列表。

  2. 在顶部菜单栏选择目标地域,然后在实例列表中单击实例名称进入实例详情页面。

  3. 在左侧导航栏单击Topic 管理,然后在页面左上角,单击创建 Topic。
  4. 在创建Topic面板中,输入要创建的Topic名称和描述,然后在左下角单击确定。

步骤四:创建Group

Group ID详细信息,请参见名词解释。

  1. 登录云消息队列 MQTT 版控制台,并在左侧导航栏单击实例列表。

  2. 在顶部菜单栏选择目标地域,然后在实例列表中单击实例名称进入实例详情页面。

  3. 在左侧导航栏单击Group 管理,然后在页面左上角单击创建 Group。
  4. 在创建Group面板中,输入Group ID,然后在左下角单击确定。

步骤五:配置MQTT.fx接入云消息队列 MQTT 版

  1. 打开MQTT.fx客户端,在其顶部菜单栏中选择Extras > Edit Connection Profiles。

  2. 在Edit Connection Profiles页面中配置相关参数,然后单击OK。

    参数

    说明

    取值示例

    Profile Name

    配置文件名称。

    MQTT Test

    Profile Type

    配置的连接类型。

    固定选择MQTT Broker,表示连接MQTT服务器。

    MQTT Broker Profile Settings

    Broker Address

    步骤二中获取的云消息队列 MQTT 版实例的接入点。

    本示例以公网接入点为例。post-cn-st21xgs****.mqtt.aliyuncs.com

    说明

    post-cn-st21xgs****为您购买的云消息队列 MQTT 版实例ID。

    Broker Port

    连接云消息队列 MQTT 版的协议端口。

    • MQTT协议端口:1883

    • SSL端口:8883

    1883

    Client ID

    客户端的唯一标识,要求全局唯一。Client ID由两部分组成,组成形式为<GroupID>@@@<DeviceID>。<GroupID>为步骤四中创建的Group ID,<DeviceID>为您自定义的设备ID。Client ID的长度限制为64个字符,不允许使用不可见字符,具体限制,请参见使用限制。

    GID_MQTT_test@@@111

    本示例中<DeviceID>自定义为111,<GroupID>为GID_MQTT_test

    。

    User Credentials

    User Name

    客户端接入云消息队列 MQTT 版需要输入用户名和密码完成认证,认证通过后才能进行消息收发。签名鉴权模式下,User Name 必须按以下三段式格式拼接:Signature|AccessKeyId|实例ID。

    其中各段说明:

    • Signature:固定前缀,表示签名鉴权模式,不可省略。

    • AccessKeyId:阿里云账号的 AccessKey ID,不能只填 AccessKey。

    • 实例ID:步骤二中创建的 MQTT 实例 ID(如 post-cn-st21xgs****)。

    Signature|yourAccessKeyID|post-cn-st21xgs****

    Password

    按照鉴权概述的描述,如果选择一机一密鉴权模式,MQTT客户端实际连接MQTT消息服务器时,connect报文中的Username和Password需要按照本文约定的规范设置,具体设置和计算方法如下:

    • Username

      由鉴权模式名称、DeviceAccessKeyId和InstanceId三部分组成,以竖线(|)分隔。一机一密模式下鉴权模式设置为DeviceCredential。

      Client ID的详细说明请参见名词解释。

    • Password

      对Client ID签名的结果。具体计算方法如下:

      举例:一个客户端的Client ID是GID_Test@@@0001,使用的DeviceAccessKeySecret是XXXXX。

      用XXXXX作为密钥,使用HMAC-SHA1方法对待签名字符串GID_Test@@@0001做签名计算得到一个二进制数组,再对该二进制数组做Base64编码得到最终的Password字符串。

      HMAC-SHA1的算法实现,各个语言都有现成的函数库,请自行搜索。

    yourAccessKeySecret

    SSL/TLS

    Enable SSL/TLS

    是否使用SSL或TLS加密协议。

    取消选中

    Protocol

    协议版本。

    TLSv1.2

    说明

    其他参数均使用系统默认值,无需设置。您也可以根据实际场景自定义参数值。

    重要

    MQTT.fx 是第三方开源工具,非阿里云官方维护。若按上述参数正确配置后仍无法收发消息或控制台显示设备离线,建议优先使用阿里云官方 SDK进行测试,以排除客户端兼容性问题。

  3. 参数配置完成后,单击Connect进行连接。

    • 右侧绿灯亮起,表示MQTT.fx和云消息队列 MQTT 版已成功连接。

    • 右侧红灯亮起,表示连接失败,您可以单击Log查看日志,根据日志信息修改配置并重新尝试连接。

    您可以在云消息队列 MQTT 版控制台对应实例下,查看设备状态,预期设备状态为在线。在云消息队列 MQTT 版控制台左侧导航栏单击设备状态查询,输入 Group ID(如 GID_MQTT_test)和 Device ID(如 111),单击查询,查询结果显示设备在线状态为在线,表示 MQTT.fx 客户端已成功接入云消息队列 MQTT 版。

    重要

    设备在控制台显示为在线状态的前提是已正确配置User Credentials(用户名和密码)。如果连接时未设置用户名和密码,MQTT协议层面可能连接成功,但设备不会在控制台显示为在线状态。请确保已按照上述步骤正确配置User Name和Password。

使用MQTT.fx订阅消息

  1. 在MQTT.fx客户端上方单击Subscribe页签。

  2. 在Subscribe页签中,在左侧Topic文本框输入步骤三中创建的Topic的名称,然后再单击文本框右侧的Subscribe。本示例以MQTT_test_topic为例。订阅成功后,该Topic会显示在订阅列表中。

    说明

    本文以父级Topic为例,若需要订阅子级Topic,直接在Topic文本框中父级Topic名称后加上子级Topic名称即可,父级Topic和各子级Topic间均使用正斜线(/)隔开,例如MQTT_test_topic/subscribe1。Topic详细信息,请参见名词解释。

    订阅成功后,在 Subscribe 页签下方的已订阅主题列表中显示 MQTT_test_topic,消息计数为 0,可对该主题执行 Dump Messages、Mute、Unsubscribe 操作。

  3. 在云消息队列 MQTT 版控制台对应实例下,单击Topic 管理,找到订阅的Topic,在其操作列单击快速体验。

  4. 在快速体验消息收发面板中,选择发送方式为控制台并在消息内容文本框中输入要发送的消息内容,例如:hello mqtt,然后单击确定。

    其中 子级 Topic 可留空。面板下方还展示了运行 Docker 容器模拟消息接收客户端的 docker run 命令,包含 TOPIC、INSTANCE_ID、ENDPOINT、DEVICE_ID、GROUP_ID、AK、SK 等环境变量参数。

    回到MQTT.fx客户端,在Subscribe页签中可以查看订阅的Topic接收到的消息。在 MQTT.fx 客户端中,单击 Subscribe Tab,可看到订阅的主题 MQTT_test_topic 已成功接收到消息 hello mqtt,QoS 为 0。

使用MQTT.fx发送消息

  1. 在MQTT.fx客户端上方单击Publish页签。

  2. 在Publish页签中,在左侧Topic文本框输入步骤三中创建的Topic的名称,本示例以MQTT_test_topic为例,然后在下面的消息文本框中输入要发送的消息内容,例如:mqtt send message,然后单击Topic文本框右侧的Publish发送消息。

    单击Subscribe页签,您可以查看到对应订阅的Topic已接收到刚才发送的消息。切换到 Subscribe 标签页,确认已成功接收到主题为 MQTT_test_topic 的消息,消息内容显示为 mqtt send message。

查看消息轨迹

进入云消息队列 MQTT 版控制台,在消息轨迹查询页面输入Group ID和Device ID然后单击查询。

返回3条消息轨迹。从下至上依次为:

  • 第1条:MQTT云消息队列 MQTT 版控制台发送到MQTT.fx的消息。

  • 第2条:MQTT.fx客户端发送的消息。

  • 第3条:推送至MQTT.fx的消息。第2条和第3条轨迹的Message ID相同,即通过MQTT.fx完成了同一条消息的自收发。

查看日志

在MQTT.fx中,单击Log页签可查看操作日志和错误日志。

2021-07-16 10:01:23,207  INFO --- MqttFX ClientModel          : attempt to addRecentSubscriptionTopic
2021-07-16 10:01:23,207  INFO --- MqttFX ClientModel          : addRecentSubscriptionTopic : de.jensd.mqttfx.entities.Topic@5d6aafa0
2021-07-16 10:01:23,208  INFO --- MqttFX ClientModel          : attempt to add PublishTopic
2021-07-16 10:01:23,211  INFO --- MqttFX ClientModel          : sucessfully subscribed to topic MQTT_test_topic (QoS 0)
2021-07-16 10:07:51,675  INFO --- MqttFX ClientModel          : messageArrived() with topic: MQTT_test_topic
2021-07-16 10:07:51,694  INFO --- MqttFX ClientModel          : messageArrived() added: message #1 to topic 'MQTT_test_topic'
2021-07-16 10:20:43,156  INFO --- MqttFX ClientModel          : rebuildMessagesList()
2021-07-16 10:20:43,159  INFO --- MqttFX ClientModel          : rebuildMessagesList()
2021-07-16 10:20:43,159  INFO --- MqttFX ClientModel          : sucessfully unsubscribed from topic: MQTT_test_topic
2021-07-16 10:20:56,155  INFO --- PublishController           : publish
2021-07-16 10:20:56,157  INFO --- MqttFX ClientModel          : attempt to add PublishTopic
2021-07-16 10:20:56,157  INFO --- MqttFX ClientModel          : sucessfully published message hello mqtt to topic MQTT_test_topic (QoS 0, Retained: false)
2021-07-16 10:21:04,226  INFO --- SubscribeController         : onSubscribe
2021-07-16 10:21:04,362  INFO --- MqttFX ClientModel          : rebuildMessagesList()
2021-07-16 10:21:04,365  INFO --- MqttFX ClientModel          : attempt to addRecentSubscriptionTopic
2021-07-16 10:21:04,366  INFO --- MqttFX ClientModel          : addRecentSubscriptionTopic : de.jensd.mqttfx.entities.Topic@5d6aafa0
2021-07-16 10:21:04,367  INFO --- MqttFX ClientModel          : attempt to add PublishTopic
2021-07-16 10:21:04,376  INFO --- MqttFX ClientModel          : sucessfully subscribed to topic MQTT_test_topic (QoS 0)
2021-07-16 10:34:14,443  INFO --- PublishController           : publish
2021-07-16 10:34:14,444  INFO --- MqttFX ClientModel          : attempt to add PublishTopic
2021-07-16 10:34:14,444  INFO --- MqttFX ClientModel          : sucessfully published message mqtt send message to topic MQTT_test_topic (QoS 0, Retained: false)
2021-07-16 10:34:14,614  INFO --- MqttFX ClientModel          : messageArrived() with topic: MQTT_test_topic
2021-07-16 10:34:14,615  INFO --- MqttFX ClientModel          : messageArrived() added: message #2 to topic 'MQTT_test_topic'
2021-07-16 11:00:13,812  INFO --- MqttFX ClientModel          : messageArrived() with topic: MQTT_test_topic
2021-07-16 11:00:13,813  INFO --- MqttFX ClientModel          : messageArrived() added: message #3 to topic 'MQTT_test_topic'
2021-07-16 11:03:40,501  INFO --- PublishController           : publish
2021-07-16 11:03:40,502  INFO --- MqttFX ClientModel          : attempt to add PublishTopic
2021-07-16 11:03:40,503  INFO --- MqttFX ClientModel          : sucessfully published message mqtt send messagefgsdfsg to topic MQTT_test_topic (QoS 0, Retained: false)
2021-07-16 11:03:40,609  INFO --- MqttFX ClientModel          : messageArrived() with topic: MQTT_test_topic
2021-07-16 11:03:40,610  INFO --- MqttFX ClientModel          : messageArrived() added: message #4 to topic 'MQTT_test_topic'

常见问题

使用 MQTT.fx 连接成功但控制台显示设备离线或无法接收消息怎么办?

若 MQTT.fx 显示连接成功(右侧绿灯亮起),但在云消息队列 MQTT 版控制台的设备状态查询页面看到设备离线,或无法正常收发消息,请按以下步骤逐一排查:

  1. 检查 User Name 格式是否正确

    确认 User Name 严格按照三段式格式填写:Signature|AccessKeyId|实例ID。

    • 不能只填 AccessKey ID,必须包含 Signature| 前缀和实例 ID 三部分。

    • 实例 ID 需与步骤二中获取的实例 ID 完全一致(区分大小写)。

  2. 检查 Password 是否与鉴权模式匹配

  3. 确认父级 Topic 已在控制台创建且名称拼写正确

    进入云消息队列 MQTT 版控制台的Topic 管理页面,确认步骤三中创建的父级 Topic 存在,且 MQTT.fx 中订阅/发布使用的 Topic 名称与控制台一致(区分大小写)。

  4. 确认 Client ID 长度未超过 64 字符

    Client ID 由 <GroupID>@@@<DeviceID> 组成,总长度不得超过 64 字符。超长会导致连接失败或设备无法正常在线。

  5. 通过控制台消息轨迹功能查看具体报错

    进入云消息队列 MQTT 版控制台,在消息轨迹查询页面,输入 Group ID 和 Device ID 查询,查看消息是否到达服务端及具体报错信息。

  6. 排除 MQTT.fx 客户端兼容性问题

    若以上排查均无异常但问题仍存在,由于 MQTT.fx 是第三方开源工具而非阿里云官方维护,建议改用阿里云官方 SDK进行测试,以判断是否为客户端兼容性问题。