为什么使用MQTT) b& s4 |+ S5 D1 J( p1 u) }
MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。特别是物联网(IoT)和嵌入式。
9 D( b2 d' G$ ^, e" j' lMQTT包容不稳定的网络,MQTT和MQ可以从诸如断开连接之类的故障中恢复,无需进一步的代码要求。但是,HTTP本身无法实现此目标,并且客户端必须重试编码,这会增加身份问题。: o Q$ R' q4 W. s0 E* M G
低功耗MQTT专为低功耗目标而设计。 HTTP设计未考虑此因素,这会增加功耗。
4 C3 K& ~3 `- J' Z$ aMQTT使用的发布/订阅消息模式,它提供了一对多的消息分发机制,从而实现与应用程序的解耦。这是一种消息传递模式,消息不是直接从发送器发送到接收器(即点对点),而是由MQTT server(或称为 MQTT Broker)分发的。客户端可以发布消息(发送方)、订阅消息(接收方)或两者兼而有之,从而可以实现多对多通信。: M3 ^7 w) n0 d, [4 o$ @; t
有三种消息发布服务质量:
6 R7 i) _+ \- G: f& x3 J3 [“至多一次”,消息发布完全依赖底层TCP/IP网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。这一种方式主要普通APP的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就收不到了。
' s V( Y/ J/ T c1 O“至少一次”,确保消息到达,但消息重复可能会发生。
7 t# ?2 _$ R' U5 d“只有一次”,确保消息到达一次。在一些要求比较严格的计费系统中,可以使用此级别。在计费系统中,消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送,确保用户收到且只会收到一次。* Z6 T8 N8 U+ i2 B3 X# `1 n; R% {
项目概述
$ V' W, G0 L* m! }* P8 ?) dgitee项目地址2 k% D* M8 U8 c( ^0 J. M( q; n; q
; m P; v' A% ^1 W Y
$ W0 D0 f6 y! \6 V j* H0 Y* {, ~
% D+ p; t) q7 V! G( J; P4 _$ U) }移植ONENET开源代码1 e; K; n b4 X: X1 e
将服务质量2修改为服务质量0;
0 r/ G( x7 S& F( ^3 u" ^: @9 T& X1 ]' ?5 \7 \7 d
9 ~+ z' m5 t& I0 q$ e) Q$ G' @/ ]- J s! W
修改服务器地址# p c: |! \6 n- I0 g
; Z* @+ s1 d/ d1 _) ~, m- #define SERVER_HOST "broker.emqx.io" // MQTT服务器域名或IP
" R0 X3 f6 O% [' v( \* d - #define SERVER_PORT "1883" // MQTT服务器端口(一般为1883不用改)
复制代码 & I Y) f1 A" j* p; E7 D
修改接收数据解析& G$ \+ D! e) u: ^
: c% Q% j0 g% [* c: @
- case MQTT_PKT_PUBLISH: //接收的Publish消息4 D9 L4 j7 q6 Z2 Y; w3 [0 v. o4 p
- ' k8 Z2 P( Q0 l' p3 ^1 w6 V1 n& _
- result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);
/ f o; B! C9 G4 V - if(result == 0). z+ P! U0 {( w
- {: ?5 a! J7 W8 Y3 ~
- UsartPrintf(USART_DEBUG, "topic: %s, topic_len: %d, payload: %s, payload_len: %d\r\n",% ?/ t- t: g1 F. x* W* ?
- cmdid_topic, topic_len, req_payload, req_len);/ m3 u( G# \. o/ U5 V. T$ I
- % h7 ^5 H, b4 x" P# w
- // 对数据包req_payload进行JSON格式解析9 }# b/ G( K) F$ ?0 c$ c5 u
- json = cJSON_Parse(req_payload);
6 Q/ U' S) w8 } O - if (!json)UsartPrintf(USART_DEBUG,"Error before: [%s]\n",cJSON_GetErrorPtr());
" u5 j, P9 p0 ~: E; F - else
7 E/ D: G4 i/ @7 ` - {
- f& v$ y; o7 R7 c! q/ { - json_value = cJSON_GetObjectItem(json , "LED");) q( `0 w7 @ j# v
- * q" R. e7 R# n6 C/ _$ C( ^
- UsartPrintf(USART_DEBUG,"json_value: [%d]\n",json_value->valueint);3 C7 G% J- _0 q) n( a
-
% d7 ?: ?) K1 p' z. S- O J3 F - if(json_value->valueint)//json_value > 0且为整形+ g& s% \ Z' { P9 O0 t! i
- {; _$ T$ C. d: ~! D7 H$ X; A
- ucLed = 1;//打开LED0 8 K# V! s- O* m: N
- }
% f& j1 _9 v- l - else# ~7 G, ^3 x* a& Z$ Z
- {
! s$ r/ r& N& k - ucLed = 0;//关闭LED0
: E* ?. e7 Q X - }6 T+ F1 k. R+ H- A
- }, Z; X: D9 Z& H- {6 v! L7 `
- cJSON_Delete(json);, y n( }$ `, d, L
- MQTT_DeleteBuffer(&mqttPacket); //删包' L% _2 n# A7 @7 r' j
- }% t* P. ~4 T. M; x: R3 p
- break;
复制代码 ; v' e( ?" \- m9 e* e5 {
使用场景
! k9 W4 S" W9 l# X引用
7 L: R' K' R4 n! _3 w) h$ G
6 j2 Q/ D. _( r5 ^/ t/ {
( f+ N, B" S, ^9 v) x0 j
' _9 S% W6 ~ y- R7 V
1 j; H5 f7 P/ y9 m1 u! `8 P5 Z: d& N9 g3 Y
————————————————/ b/ H& r7 R5 r. A V# H
版权声明:Flynnsin$ s& q1 j+ w: N4 f/ u1 e
2 O. y0 i+ r* b2 ~
0 W5 c- ~7 ? r1 N |