草庐IT

(一)MQTT连接阿里云物联网平台(小白向)

弦急 2023-04-20 原文

目录


前言

本次项目使用的是MQTT协议,首先需要了解一下使用的MQTT协议,本篇文章将简单介绍MQTT协议的原理,接着讲解阿里云物联网平台的使用方法,并讲解如何使用网络调试助手模拟连接阿里云物联网平台及mqtt.fx如何连接阿里云平台物联网设备。


一、MQTT协议基本介绍

在MQTT协议通讯中,有两个最为重要的角色。它们分别是服务端和客户端。

MQTT服务端
MQTT服务端通常是一台服务器。它是MQTT信息传输的枢纽,负责将MQTT客户端发送来的信息传递给MQTT客户端。MQTT服务端还负责管理MQTT客户端。确保客户端之间的通讯顺畅,保证MQTT消息得以正确接收和准确投递。

MQTT客户端
MQTT客户端可以向服务端发布信息,也可以从服务端收取信息。我们把客户端发送信息的行为成为“发布”信息。而客户端要想从服务端收取信息,则首先要向服务端“订阅”信息。“订阅”信息这一操作很像我们在视频网站订阅某一部电视剧。当这部电视剧上新后,视频网站会向订阅了该剧的用户发送信息,告诉他们有新剧上线了1

总之,就是客户端不会直接与另一客户端进行通信,而是通过服务器存储并转发消息。而其中说到的订阅操作是我们后面连接上服务器后之后想要收到消息时需要进行的操作。


二、初步了解阿里云物联网平台创建产品步骤

使用过阿里云生活物联网平台(飞燕平台)后将无法使用公共实例(新版),使用后会切换回公共实例(旧版)且无法再次变更。新版和旧版最大的区别就是是否收费(旧版的公共实例在实例概览处无ID和开通时间):
公共实例(新版):收发信息无需收费
公共实例(旧版):连接时长及收取费用见公共实例计费方式

接着进入正题,如何在旧版阿里云公共实例平台创建产品:

  1. 注册账号进入阿里云物联网平台

  2. 选择创建产品

  3. 创建产品如下图所示

  4. 在刚刚的产品界面选择刚刚创建的产品旁的管理设备按钮

  5. 单击添加设备

  6. 对创建设备进行命名等信息创建(记住devicename最好要填写方便输入的,随机生成的老难打后面,问就是试过)

  7. 创建成功,此时显示未激活

  8. 点击查看进入产品页面,选择下图DeviceSecret旁的查看

  9. 选择一键复制即得到当前产品实现静态连接测试所需要的信息


三、求解阿里云登录所需的参数

名字形式
HOST_PORT1883
HOST_NAME*.iot-as-mqtt.&.aliyuncs.com (可在MQTT连接参数旁的查看-mqtthosturl中复制)
CLIENT_ID#|securemode=3,signmethod=hmacsha1| (前面的securemode表示加密方法,改为3表示不加密;后面的signmethod表示选取加密方法,这里测试选择简单的hmacsha1算法)
USER_NAME#&*
PASSWORDclientId#deviceName#productKey* (需进行hmacsha1加密,加密方法见下文)

*:productkey
#:devicename设备名称
&:所处地名
其中PASSWORD的hmacsha1加密可进入在线加密网站进行求解,在加密前字符串中输入加入自己三元组参数的结果,而后在密码处输入自己的密码,并选择hmacsha1加密方式,最终结果如下图所示。

最后得到的参数如下表所示

名字结果
HOST_PORT1883
HOST_NAMEa1yjZLBNYf0.iot-as-mqtt.cn-shanghai.aliyuncs.com
CLIENT_IDtest|securemode=3,signmethod=hmacsha1|
USER_NAMEtest&a1yjZLBNYf0
PASSWORDa1d68e2804f5b2481146be1479711fa1353fe08d

四、使用网络调试助手模拟产品登录

1.转换为MQTT登录报文过程

根据前面求出的参数,将其转换为MQTT协议所需要的形式,具体报头形式可参考mqtt报文解析中的2.5。

本例中的报头为:
10 ?? 00 04 4D 51 54 54 04 C2 00 78
其中第二个字节??表示10 ??后的报文长度的十六进制,需在计算后填入,其他可原封不动保留。

数据部分分为前面表中得到的CLIENT_ID,USER_NAME和PASSWORD,其中CLIENT_ID求解为:
?? ?? 74 65 73 74 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C
其中?? ??后面为CLIENT_ID转换为十六进制后的数据,前面的?? ??表示后面数据的长度,这里长度为38个,转换为十六进制可求出?? ??为00 26,即USER_NAME求解为:
00 26 74 65 73 74 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C
其中USER_NAME求解为:
?? ?? 74 65 73 74 26 61 31 79 6A 5A 4C 42 4E 59 66 30
其中?? ??后面为USER_NAME转换为十六进制后的数据,前面的?? ??表示后面数据的长度,这里长度为16个,转换为十六进制可求出?? ??为00 10,即USER_NAME求解为:
00 16 74 65 73 74 26 61 31 79 6A 5A 4C 42 4E 59 66 30
同理可得PASSWORD为:
00 28 61 31 64 36 38 65 32 38 30 34 66 35 62 32 34 38 31 31 34 36 62 65 31 34 37 39 37 31 31 66 61 31 33 35 33 66 65 30 38 64

最后再倒回去求解报头的10 ??中的??,??后数据长度为110,转换为十六进制求得??为6E,即本次登录报文为:
10 6E 00 04 4D 51 54 54 04 C2 00 78 00 26 74 65 73 74 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 00 10 74 65 73 74 26 61 31 79 6A 5A 4C 42 4E 59 66 30 00 28 61 31 64 36 38 65 32 38 30 34 66 35 62 32 34 38 31 31 34 36 62 65 31 34 37 39 37 31 31 66 61 31 33 35 33 66 65 30 38 64

2. 测试

使用网络调试助手,设置协议类型为TCP Client,服务IP地址为139.196.135.135,服务器端口为1883,发送接收区均设置为HEX格式,然后将登录报文发送,可见接收区收到了20 02 00 00,表示登录成功!

同时在产品处也可以发现产品已连接。

登录后需要进行订阅和发布操作,因为我采用的JSON格式的报文,因此这里的订阅报文的具体含义及操作可以参照mqtt报文解析文章。

补充:将数据转换为十六进制方法

可将网络协议设置为UDP,并连接本地IP地址,而后在对话框中输入需要转换的数据,点击右下角发送区设置的按十六进制发送,即可将数据转换为十六进制数据。单击发送会在右下角有发送数据数,可快速得到相应数据。

在后续逐渐熟悉操作后还可以使用简单的数据库语句通过阿里云平台的数据流转实现两个产品间的数据转发,其过程可以参阅MQTT登录云服务器的讲解。


五、使用 mqttfx 登录阿里云


点击connect旁边的齿轮进入设置页面,并按照前面求出的表格结合下表对应填好其中所需要的参数。

名字对应前面的名字
Broker AddressHOST_NAME
Broker PortHOST_PORT
Client IDCLIENT_ID
User NameUSER_NAME
PasswordPASSWORD

将对应数据填好后如下图所示,点击OK。

点击connect即可连接,这时在设备中也可发现产品已经连接。

在之前创建的test01产品中找到topic类列表(注意不是设备),选择一个订阅权限的主题,将其复制到mqttfx的Subscribe框中,并将${deviceName}修改为你的设备名字并点击subscribe。


订阅后返回test设备页面(注意不是产品),在TOPIC列表中就可以看到已订阅的topic,点击发布消息,输入消息数据123后可在mqttfx上看到消息。


至此,已经完成了订阅一个主题的操作。接着讲讲发布消息的操作。
首先需要在test01产品中设置对应的功能。选择产品(注意不是设备)。

点击编辑草稿,添加自定义功能如下图所示:

同理添加湿度如下图所示:

记住下图中的标识符,这是在发布JSON消息时数据发布的重要依据。接着点击左下角的发布上线即可添加对应功能

接着在test01产品(注意不是设备)复制具有上报属性的主题/sys/a1yjZLBNYf0/\${deviceName}/thing/event/property/post,将其中的\${deviceName}换为自己的设备名字后粘贴到mqttfx中的publish框中。

接着在下列空白处输入如下JSON数据,并点击publish。

{
 "method" : "thing.event.property.post",
 "params" : {
   "temperature" : 25, 
   "Humidity":26,
    }, 
    "version" : "1.0.0"
}


可见test设备(注意不是产品)中的物模型数据-运行状态中的数据已经刷新。

至此,恭喜你已经完成了MQTT服务器的连接,主题的订阅,数据的发布过程。


总结

本文带领大家从MQTT的原理定义,到阿里云物联网平台产品及设备的创建,再到MQTT登录报文的分析,再到使用MQTTfx连接服务器、订阅主题、发布消息。其实第四点中登录报文的讲解是可有可无的,但是若是想更深入的了解数据传输,协议运作过程,接触这些报文,拾起计算机网络课程的知识是必不可少的。
最后也希望本文能够帮助到你!如果有什么问题,欢迎在评论区里一起沟通!


  1. MQTT是什么 ↩︎

有关(一)MQTT连接阿里云物联网平台(小白向)的更多相关文章

  1. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  2. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  3. 阿里云国际版免费试用:如何注册以及注意事项 - 2

    作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。​关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐

  4. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

  5. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  6. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  7. ruby - Faye WebSocket,关闭处理程序被触发后重新连接到套接字 - 2

    我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d

  8. ruby-on-rails - 什么会导致与 APNS 的连接间歇性断开连接? - 2

    我有一个ruby​​脚本可以打开与Apple推送服务器的连接并发送所有待处理的通知。我看不出任何原因,但当Apple断开我的脚本时,我遇到了管道损坏错误。我已经编写了我的脚本来适应这种情况,但我宁愿只是找出它发生的原因,这样我就可以在第一时间避免它。它不会始终根据特定通知断开连接。它不会以特定的字节传输大小断开连接。一切似乎都是零星的。您可以在单个连接上发送的数据传输或有效负载计数是否有某些限制?看到人们的解决方案始终保持一个连接打开,我认为这不是问题所在。我看到连接在3次通知后断开,我看到它在14次通知后断开。我从未见过它能超过14点。有没有人遇到过这种类型的问题?如何处理?

  9. ruby - 如何断开现有的 ruby​​ 续集与数据库的连接? - 2

    我的意思是之前建立的那个DB=Sequel.sqlite('my_blog.db')或DB=Sequel.connect('postgres://user:password@localhost/my_db')或DB=Sequel.postgres('my_db',:user=>'user',:password=>'password',:host=>'localhost')等等。Sequel::Database类没有名为“disconnect”的公共(public)实例方法,尽管它有一个“connect”。也许有人已经遇到过这个问题。我将不胜感激。 最佳答案

  10. ruby-on-rails - 遗留数据库的 ActiveRecord 连接表 - 2

    我有一个遗留数据库,我正在努力让ActiveRecord使用它。我遇到了连接表的问题。我有以下内容:classTvShow然后我有一个名为tvshowlinkepisode的表,它有2个字段:idShow、idEpisode所以我有2个表和它们之间的连接(多对多关系),但是连接使用非标准外键。我的第一个想法是创建一个名为TvShowEpisodeLink的模型,但没有主键。我的想法是,由于外键是非标准的,我可以使用set_foreign_key并进行一些控制。最后,我想说一些类似TvShow.find(:last).episodes或Episode.find(:last).tv_sho

随机推荐