Paho MQTT 客户端接入阿里云物联网平台(4)| 学习笔记

简介: 快速学习 Paho MQTT 客户端接入阿里云物联网平台(4)

开发者学堂课程【基于STM32的端到端物联网全栈开发Paho MQTT 客户端接入阿里云物联网平台(4)】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/574/detail/7940


Paho MQTT 客户端接入阿里云物联网平台(4)


Paho MQTT 客户端接入阿里云物联网平台示例操作

项目例程软件架构:
应用程序:

1.节点端业务程序

2.阿里云 MQTT 连接适配层

中间件:

1.Paho MQTT embedded C

2.mbedTLSHMAC-SHA1

3.网络接口抽象

底层驱动:

1.STM32L4 Cube HAL 硬件抽象层

2.传感器驱动

3.WIFI 模块驱动

image.png

//例程软件中的 Paho MQTT 协议栈向下通过 ST 提供的网络接口抽象层,来调用底层的 wifi 驱动实现网络数据的通信,向上提供 MQTT API 函数给阿里云 MQTT 连接适配层来完成应用程序的功能

//在接下来的课程中将分别介绍代码中实现网络通信的分层结构,发送和接收数据流的传递过程以及 Paho 向下和网络接口的适配以及向上和阿里云 MQTT 连接适配层的实现

各个软件层中主要对应的c文件以及他们之间的调用关系

---------------1.net_wifi 适配  Wifi 驱动

2.net_c2c 适配 C2c 驱动

3.net_eth 适配 Eth 驱动

image.png

//上边的文件通过下边的软件层通过颜色进行了对应

//节点中的业务程序主要在 main.c 业务中实现

//阿里云 MQTT 连接适配层包括 Ali_iotclient.c 文件和 Ali_iot_network_wrapper.c 文件

//Ali_iotclient.c 文件实现了阿里客户端的功能,包括构建 MQTT 连接的参数,与 MQTT 服务器建立连接,订阅发布消息等函数

//Ali_iot_network_wrapper.c 文件中实现了 MQTT 通信网络接口的封装

//MQTTClient.c Paho 协议栈的文件,它提供了众多 API 给上方的 Ali_iotclient.c 中的函数调用

//net.c 是 ST 的网络接口抽象层的文件,MQTTClient.c 通过 Ali_iot_network_wrapper.c 中封装的网络接口函数向下调用 net.c 中对应的函数,再向下调用 wifi 驱动。在本次例程中只使用到了 wifi 驱动,这个软件结构的好处,是可以很方便的移植到比如2G/3G以及以太网这些网络连接方式去,只需要将 net.c 文件部分下的.c 文件进行替换就能完成,上方的文件代码均不会受到影响。

后端配置代码:    

//AliIoT 路径下有三个适配文件:

Ali_iotclient.c

Ali_iot_network_wrapper.cmqtt_msg_handler.c 文件

// Ali_iot_network_wrapper.c 下封装了5个函数,分别是与服务器创建 tcp 连接,与服务器断开 tcp 连接以及向下对网络接口发送和接收数据的两个函数

//mqtt network 这个函数是在向 mqtt 协议栈新建一个网络接口,并且注册相关的数据收发的函数

// Ali_iotclient.c 文件中主要实现阿里客户端的一些功能,比如如何根据三元组信息来构建 mqtt 服务器的地址,如何得到 mqtt 的主题,如何得到 mqtt 连接的用户名,和 mqtt 连接的密码,还有与 mqtt 服务器创建连接向服务器发送消息和订阅主题的函数

//mqtt 连接创建的过程:

main 函数中,前面的初始化操作和 wifi 都已经连接之后,就会开始与阿里云 iot 平台创建 mqtt 的连接,在 main函数中会调用 connect2Aliiothub 函数,此函数是在 Ali_iotclient.c 文件中实现的,此函数首先会根据三元组的信息来构建 mqtt 服务器的地址。得到服务器的地址后先调用 mqtt_connect_network 函数来与服务器建立 tcp 的连接,此函数是在 Ali_iot_network_wrapper.c 文件中实现的。在 mqtt_connect_network 函数中会调用 net.c 文件中所提供的向上的统一的网络接口函数来实现对网络的一些操作,

首先它会先调用 net_sock_create 来创建一个 socket,在此函数中,他会根据你所使用的不同网络接口来调用对应不同的函数来创建一个 socketsocket 创建成功后,它会将对应的 socket 的操作的函数注册到 sock 结构体中。上层的应用程序来通过 sock 这个结构体来做对应的操作时,实际调用的就是它已经注册的函数。

比如要通过 sock 来进行发送数据,接收输入,那么它调用的就是 net_sock_send_tcp_wifi net_sock_sen_recv_wifi 两个函数,这些函数的实现是在 net.tcp.wifi.c 文件中。mqtt_connect_network 函数首先会创建一个 sock,然后在创建 sock 的过程中,已经注册好一系列对 socket 操作的函数,接收数据,发送数据,断开连接等函数都已经注册成功,然后在对 socket 进行一些配置,最后通过 socket 与服务器建立 tcp 的连接。

#include "main.h"

#include "Ali_iot_network_wrapper.h"

int mqtt_connect_network(letwork* n, const char * host_addressint port)

{

int mqtt_socket_send(Network *network,unsigmed char *bufint len,int timeout){

{

int mqtt_socket_recv(Network *network,unsigmed char *bufint len,int timeout)

{

int mqtt_socket_disconnect(Network *network)

{

//@sz, nev a MQTT netvork interface vith WIFI module

//must called before baidu_connect_netvork_tls/baidu_connect_network

int mqtt_network _new (Network *network)

{

network->my socket = 0;

network->mqttread = mqtt_socket_recv;

network->mqttwrite = mqtt_socket_send;

network->disconnect = mqtt_socket_disconnect;

return SUCCESS;

}

如何构建服务器地址:
extern int PrepareMqttPayload (char * PayloadBuffer,int PayloadSize) ;

extern void Parameters_message_handler(MessageData * data) ;

extern void Service_message_handler(MessageData * data) ;

void calpassword(void) ;

int get_mgtt_server_addr(char* host_addrchar* region_id,char* product_key )

{

//$( YourProductKey}.iot-as-mqtt.$ { YourRegionId}.aliyuncs.com:1883

uint32_t return_len=0;

return_len = snprintf(host_addr,NQTT_CLIENT_INFO_S12E,"4s.iot-a38-mgtt.i8.aliyuncs.com" ,product_key ,regic

n_id) ;

if (return_len >= MQTT_CLIENT_INFO_SIZE)

{

mag_info ("no enough space for host address\n") ;

return -1;

}

msg_info ("MQIT server address is :is\n",host_addr);

return 0;

}

int build_mgtt_topic(void)

{                              

MQTT连接过程:

//WIFI SSID/passov rd config and initializationl

// and config device certificate

ret = initPlatform() ;

if (ret! =0)

{

mag_info ("wifi initial failed! \n");

while(1) ;

// connect to Ali Iot platformret = connect2Aliiothub () :;

if (ret!=0)l

mag_info ("MQIT connection failed! \n");

while(1) ;

}

// subscribe to topicsdeviceSubscribe () ;

/ *USER CODE END 2* /

/*Infinite loop * /

/* USER CODE BEGIN WHILE*/while (1)

{

//MQTT reconnection check

if (rebuildMQTTConnection ( )==0){

doMqttYield( );

/*USER CODE END WHILE*/

int net_sock_create_tcp_wifi(net_hnd_t nethndnet_ockhnd_t * sockhndnet_proto_t proto)

int rc = NET_ERR;

net_ctxt_t *ctxt = (net_ctxt_t *) nethnd;

net_sock_ctxt_t *sock = NULL;

sock = net_malloc (sizeof (net_sock_ctxt_t) );

if (sock == NULL)

mag_error ("net_sock_create allocation failed.in");

rc = NET_ERR;

else

memset (sock, 0, sizeof (net_sock _ctxt_t));sock->net = ctxt;

sock->next = ctxt->sock_list;

sock->methods.create = (net_sock_create_tcp_wifi) ;

sock->methods.open= (net_sock_open_tcp_wifi);

sock->methodg.recv= (net_sock_recv_tcp_wifi);

sock->methoda.send= (net_sock_send_tcp_wifi);

sock->methods.close= (net_sock_close_tcp_wifi) ;

sock->methods.destroy=(net_sock_destroy_tcp_wifi) ;

sock->proto= proto;

sock->blocking= NET_DEFAULT_BLOCKING;

sock->read_timeout= NET_DEFAULT_BLOCKING_READ_TIMEOUT;sock->write_timeout= NET_DEEAULT_BLOCKING_WRITE_TIMEOUT;

ctxt->sock_list= sock; /* Insert at the head of the list */

*sockhnd = (net_sockhnd_t) sock;

rc = NET_OK;

}

return rc;      

网络分层及数据流:

代码中实现网络通信的分层结构,发送和接收数据流的传送过程

//这里所说的网络分层并不是指 tcp 的网络分层,而是指代码中实现网络接口调用程序的时候通过网络接口抽象层,也就是下图中的蓝色部分,将底层实际的网络接口,绿色的 WIFI 驱动部分,与上层的应用程序,黄色的部分独立开,尽量保证底层网络接口的变化不会对上层应用程序产生影响。WIFI 模块驱动也分为了三层,在 emw3080_io.c 文件中是最低层跟外设打交道的部分,包括初始化引脚,从窗口读取和发送数据。

emw3080.c 文件中是对 at 指令的实现。wifi.c wifi 底层驱动和 wifi 网络层面抽象层的接口。从 tcp ip 网络分层的角度,在本例程中的代码仅仅实现了应用层的 mqtt 协议,传输层和网络层都是在 wifi 模块中实现的,从串口传给wifi 模块以及从 wifi 模块接收的都是已经封装完毕的 mqtt 数据包。传输层 tcp 和网络层封装都是由 wifi 模块完成的。

//图中的箭头是接收和发送数据传递的过程

//绿色箭头指发送和接收网络数据,例如发送温湿度信息,接收云端下发的温度阈值。紫色的箭头是 mcu 控制 wifi 模块的 at 指令以及返回值,比如连接 wifi 热点,查询固件版本等等。对于这类指令,只需要将执行的结果返回到上层的应用程序不需要将收到的具体数据向应用层传递。

//图中粉色的变量是数据在传递过程中保存的位置

//应用数据的发送的过程:比如程序要将检测到的温湿度的值从 wifi 发送到云端,应用程序首先会调用 Paho mqtt publish 函数来发送温湿度信息,在 Paho 协议栈中它会将数据封装成数据包的格式并拷贝到 mqtt_write_buf 中,然后通过 mqtt_socket_send 函数向网络接口发送。

通过网络抽象层的函数 net_sock_send net_sock_send_tcp_wifi 来调用 wifi 模块的驱动最后通过EMW3080_IO_Send 函数发送到串口,通过串口发送到 wifi 模块。

//对于云端下发的数据:wifi 模块通过串口将包含温湿度阈值 mqtt 数据包发送,数据首先会保存到 Uart Ring Buffer中,Paho 协议栈中会通过 mqtt 的函数不断的查询是否有新的数据收到,mqtt yarn 的函数会调用 mqtt_socket_recv再通过网络抽象层的函数来调用 WIFI 模块的驱动函数,查询对应的 Socket Buffer 中是否有未读出的数据,如果有就将数据拷贝到 MQTT_read.buf 中,如果则会通过 pullSocktData 函数将串口中 Ring Buffer 新的数据读取到 Socket Buffer 中再拷贝到 MQTT_read_bufMQTT_read_buf 中的数据在 Paho 协议栈中进行分析,再将真正的负载数据,就是温度阈值取出并提供给上层应用程序。

//除了应用数据流的接收,还有连接wifi热点,查询固件版本的 ak 指令的发送和返回值的接收,这部分数据的传递主要在 WIFI 模块驱动这层完成,就是紫色箭头指示的部分,这部分 ak 指令的发送主要在 net_if_int 函数中触发,程序初始化 wifi 模块时调用了 net_interface_ination,然后再此函数中完成 wifi 模块的初始化,wifi 固件版本的查询,以及 wifi 热点连接的工作。

以连接 wifi 热点为例,分析紫色部分传递数据的操作:

连接 wifi 热点是通过调用 WIFI_Connect 函数完成,在这个函数中会调用 emw3080中的函数,在此函数中会进行连接 wifi 热点的 at 指令的组装,然后保存在 Atcmd_buf 中通过 runAtCmd 函数,将数据通过串口发送到 wifi 模块,同时它继续在 runAtCmd 中等待模块发回的at指令返回值,在等待返回值的过程中,通过调用 EMW3080_IO_Receive函数查询串口的 Ring Buffer 中是否收到 wifi 模块的返回值。

问:串口的 Ring Buffer 中既有需要传递到应用层的数据,又有只需要在 WIFI 模块驱动层进行数据处理的数据,程序是如何区分两类数据的呢?

答:wifi 模块在发来的每一个数据都有一定的标识,用来说明这一帧数据的类型,比如 wifi 模块发送从云端收到的温度阈值数据包时,会加上 cip 英文数据的头,从这个标识就可以区分不同的数据包,然后进行数据处理。

网络数据产生/消耗层:Paho

image.png

网络接口:

image.png

WIFI 模块驱动:

image.png

设备端向云端发送数据的过程:

int devicest,atusPub (void)

{

int ret;

MQTTMessage MQTT_mag;

ret =0;

MQTT_msg.qos = Q0S1;  //QoS1 ;

MQTT_msg.dup = 0;//The DUP flag MST be set to 1 by the Client or Server vhen it attemptsto re-deliver a PUBLISH Packet

// The DuP flag MUST be set to 0 for all Qos 0 messages

MQTT_msg.retained = 1; //the Server MJsT store 757 the application Message and its Qos

MQTT_mag.payload = payload_buf;

// TODO:prepare pub payload,@sz

payload_buf [0]= GetTemperaturevalue ( ) ;

payload_buf [1]=GetHumvalue () ;

payload_buf[2]= GetTempratureThreshold( ;

MQTT_mag.payloadlen = 3;

if ( (ret=MQITPublish(zClient,temp_hum_topic, &MQTT_mag)) != 0){

mag_error ("Failed to publish data. td " ,ret) ;

mag_info(": temprature = %d,humidity = %d\n\n",GetTemperatureValue () ,cetHumValue());

}

数据接收的过程:

/**

@brief send data over the vifi connection.

*@paramBuffer: the buffer to send

*@paramLength: the Buffer's data size.

*@retval Returns EMW3080_OK on success and EM3080_ERROR othervise.

*/

EMW3080_StatusTypeDef EMNN3080_SendData(uint8_t socket,uint8_t* Bufferuint32_t Lengthuint32_t Timeout)

EMw3080_statusTypeDef Ret = EMw3080_OK;

if(Buffer != NULL)

uint32_t tickstart;

{

/ *Construct thecommand * /

memset(Atcnd, '1o",MAX_AT_CMD_SIZE);

sprintf( (char * )AtCmd,"AT+CIPSEND=%lu,$lusc", socket,Length,'r');

/ *Tne command doesn't have a return command

until the data is actually sent. Thus ve check here whether

ve got the '>' prompt or not. */

Ret = runAtCmd (AtCmdstrlen ((char *)AtCmd)(uint8_t*)AT_SEND_PROMPT_STRINGTimeout) ;

/ * Return Error */

if (Ret != EMw3080_oK){

return EMN3080_ERROR;

}

/ send the data */

Ret = runAtCmd (Buffer,Length,(uint8_t*)AT_OK_STRINGTimeout) ;

return Ret;

}

驱动和应用层数组定义:

1.Buffer 名称:MQTT_write_buf

默认大小:MQTT_BUFFER_SIZE512字节)
定义所在位置:Ali_iotclient.c
注释:

image.png

2.Buffer 名称:MQTT_read_buf

默认大小:MQTT_BUFFER_SIZE512字节)
定义所在位置:Ali_iotclient.c
注释:

image.png

3.Buffer 名称:AyCmd

默认大小:MAX_AT_SIZE(256字节)
定义所在位置:emw3080.c
注释:

image.png

4.Buffer 名称:RxBuffer

默认大小:MAX_RX_SIZE(1500字节)

定义所在位置:emw3080.c

5.Buffer 名称:WIFIRxBuffer

默认大小: RING_BUFFER_SIZE(1024字节)

定义所在位置:emw3080_io.h

6.Buffer 名称:”sock buffer”

默认大小:MAX_SOCKET_SIZE(512字节)定义所在位置:emw3080.h

WIFI_OpenClientConnection函数中分配内存

Paho MQTT客户端对下(网络连接)的适配

1.  网络接口的适配

typedef struct Network Network;

struct Network

net_sockhnd_t my_socket;

int (*mqttread) (Network*, unsigmed char* , int,int) ;

int (*mqttwrite)(Network* , unsigmed char* , int,int) ;

int (*disconnect)(Network*) ;

};

2.  Timer 的适配

struct Timer {

uint32_t init_tick;

uint32_t timeout_ms;

};

typedef struct Timer Timer;

void TimerCountdownMS(Timer* timerunsigmed int timeout_ms);

void TimerCountdown (Timer* timerunsigmed int timeout);

int TimerLeftMS(Timer* timer);

char TimerIsExpired(Timer* timer);

void TimerInit(Timer* timer) ;

3.  returnCode 枚举与 ST HAL 库的不兼容

Paho MQTT Client 的调用

1.MQTTClientlnit

初始化 MQTT 客户端

2.MQTTConnect

与服务器建立 MQTT 连接

3.MQTTSubscribe

向服务器订阅消息主题,并注册收到消息后的回调函数

4.MQTTPublish

向服务器发布某个主题的消息

5.MQTTYield

根据应用调整周期调用的间隔

Paho MQTT 客户端对上(阿里云 loT)的适配

与阿里云 MQTT 服务器连接需要的参数

1.用户名/密码

2.MQTT ClientID

3.保活时间

4.Cleansession

5.MQTT 服务器域名

typedef struct{

{

/** The eyecatcher for this structure. must be MQTC.*/

char struct_id[4];

/**The version number of this structure.Must be 0 */

int struct_version;

/**version of MQTT to be used. 3 = 3.1 4= 3.1.1

*/

unsigmed char MQITVersion;

MQTTString clientID;

unsigmed short keepAliveInterval;

unsigmed char cleansession;

unsigmed char willElag;

MQTTPacket_wil10ptions will;

MQTTString username;

MQITString password;

}MQTTPacket_connectData;  

构建 MQTT 服务器域名:

MQTT 服务器域名:
${YourProductKey}.iot-as-mqtt.${YourRegionld}.aliyuncs.com:1883

image.png

举例:
1.
服务器域名:

a1b05UeAQ6M.iot-as-mqtt.shanghai-cn.aliyuncs.com

2.端口:1883    

构建 MQTT ClientID

MQTT ClientID: clientld+"[Isecuremode=3,signmethod=hmacsha1,timestamp=132323232

clientld:客户端自己定义的ID号,可以使用 MAC 地址
3:
安全模式,可以选2TLS 直连)和3TCP 直连)

hmacsha1:签名算法支持:

hmacmd5

hmacsha1

hmacsha256
132323232:当前的时间戳。可以通过 HAL_GetTick 获取当前时间戳。

注意:
如果 clientld“b0f8933b9467”',签名算法选择 hmacsha1,当前时间戳为24081

MQTTClientID 为:“b0f8933b9467|securemode=3,signmethod=hmacsha1,timestamp=24081|'    

构建 MQTT 用户名:MQTT 用户名:DeviceName+&+ProductKey

举例:MQTT 用户名就是“smartthermometer&a1b05UeAQ6M”  

构建 MQTT 密码:

MQTT 密码=sign_hmac(DeviceSecret,content)

image.png

Mbedtls:
Demo IAR
工程      

Mbedtls 协议包              

MQTT 主题与消息负载格式:

1.功能:设置温度阈值

MQTT 主题:${productKey}/${deviceName}/tempThresholdSet
操作权限(设备):订阅

消息方向:下行

负载格式:一个字节:温度阈值。直接二进制传输,例如:0x1E 代表30

2.功能:解除警报

MQTT 主题:${productKey}/${deviceName}/clearAlarm
操作权限(设备):订阅

消息方向:下行

负载格式:一个字节,固定位0x01

3.功能:高温报警

MQTT 主题:S{productKey}/${deviceName}/tempAlarm
操作权限(设备):发布

消息方向:上行

负载格式:一个字节,固定位0x01

4.功能:上报属性

MQTT 主题:S{productKey}/${deviceName}/tempHumUpload
操作权限(设备):发布

消息方向:上行

负载格式:  Byte1:温度值

Byte2:湿度值

Byte3:温度阈值

MQTT 订阅消息的回调函数:

image.png

Demo 参数输入:
需要保存在 MCU 闪存中的信息:

1.WIFI 配网参数(串口输入)

2.阿里云 loT 平台三元组信息(串口输入)

3.温度报警阈值(云端下发)      

Demo 参数存储:

1.MCU 用户闪存容量2M,页大小4K(双 bank 下)

2.取末尾32K 作为用户参数存储区

Sensor 数据的读取(1

Sensor 数据的读取(2

项目例程内存占用:

总内存占用(使用 IAR v8.32.3,最高优化等级)

1.Flash52924字节

2.Ram:10874字节(包括4KB 堆栈)

主要模块内存占用:

image.png

相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
2月前
|
消息中间件 缓存 物联网
MQTT常见问题之MQTT发送消息到阿里云服务器被拒如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
消息中间件 DataWorks 物联网
MQTT问题之接入阿里云物联网平台如何解决
MQTT接入是指将设备或应用通过MQTT协议接入到消息服务器,以实现数据的发布和订阅;本合集着眼于MQTT接入的流程、配置指导以及常见接入问题的解决方法,帮助用户实现稳定可靠的消息交换。
211 1
|
29天前
|
监控 安全 物联网
阿里云mqtt简介和使用流程
本文介绍了阿里云MQTT的准备工作、简介和使用流程。首先,用户需要注册阿里云账号并完成实名认证。接着,通过阿里云物联网平台创建产品和设备,获取连接所需的Broker Address、Port、Username和Password。然后,使用MQTT客户端(如MQTTX)配置这些信息进行连接,并激活设备。最后,创建并订阅/发布自定义Topic,实现设备间的通信。阿里云MQTT是一个适用于物联网设备的轻量级通信协议,提供高并发、高可靠性的服务,广泛应用于各种物联网场景。
阿里云mqtt简介和使用流程
|
29天前
|
消息中间件 传感器 网络协议
阿里云MQTT简介和使用流程
以下是内容的摘要: 该文主要介绍了在阿里云上搭建 MQTT 服务器的步骤。首先,需要注册阿里云账号并进行实名认证。然后,购买阿里云 MQTT 实例,选择合适的类型、地域、连接和消息限制。接着,创建产品和设备,命名并上线,获取 MQTT 连接的相关信息,包括 ProductKey、DeviceName 和 DeviceSecret。通过提供的 MQTT.fx 工具,设置 MQTT 客户端连接参数,包括 Broker 地址、端口、用户名和密码。最后,使用 MQTT.fx 测试连接,实现数据的上报和接收,验证 MQTT 服务器的配置是否成功。
|
1月前
|
消息中间件 存储 JavaScript
阿里云IOC物联网异步处理基础概念
该内容介绍了异步处理基础和消息队列的相关概念。首先,同步处理指任务完成后才能执行其他操作,而异步则允许任务并行执行,不阻塞程序。异步能提高系统并发性和响应性,但也增加复杂性和资源消耗。接着,提到了消息队列,包括生产者、消费者、队列、broker和topic等概念,并指出在IoT中,设备作为生产者发送消息到特定topic,消费者从队列获取数据。最后,简要介绍了AMQP协议,它是用于应用程序间消息传递的开放标准,常用于分布式系统和物联网,如RabbitMQ和Apache Qpid。课程将以Apache Qpid为例接收IoT数据。
132 6
阿里云IOC物联网异步处理基础概念
|
1月前
|
网络协议 Java 物联网
阿里云服务器上搭建 MQTT服务
阿里云服务器上搭建 MQTT服务
|
1月前
|
弹性计算 前端开发 Java
使用阿里云 mqtt serverless 版本超低成本快速实现 webscoket 长链接服务器
使用阿里云 MQTT Serverless 可轻松实现弹性伸缩的 WebSocket 服务,每日成本低至几元。适用于小程序消息推送的 MQTT P2P 模式。前端需注意安全,避免 AK 泄露,采用一机一密方案。后端通过调用 `RegisterDeviceCredential` API 发送消息。示例代码包括 JavaScript 前端连接和 Java 后端发送。
257 0
|
1月前
|
域名解析 JSON 监控
Mqtt学习笔记--接入阿里云(2)
Mqtt学习笔记--接入阿里云(2)
46 1
|
2月前
|
消息中间件 API PHP
阿里云OpenAPI RocketMQ 5.0的PHP收发消息文档
【2月更文挑战第23天】阿里云OpenAPI RocketMQ 5.0的PHP收发消息文档
58 7
|
2月前
|
网络协议 C语言
【开源视频联动物联网平台】libmodbus库写一个Modbus TCP客户端
【开源视频联动物联网平台】libmodbus库写一个Modbus TCP客户端
29 0

相关产品

  • 物联网平台