MQTT总结一:paho_mqtt
交叉编译
使用make方式编译
修改MakeFile裁剪编译选项
# 修改 build 目标,只编译动态库
# build: | mkdir ${MQTTLIB_C_TARGET} ${MQTTLIB_CS_TARGET} ${MQTTLIB_A_TARGET} ${MQTTLIB_AS_TARGET} ${MQTTVERSION_TARGET} ${SYNC_SAMPLES} ${SYNC_UTILS} ${ASYNC_SAMPLES} ${ASYNC_UTILS} ${SYNC_TESTS} ${SYNC_SSL_TESTS} ${ASYNC_TESTS} ${ASYNC_SSL_TESTS}
build: | mkdir ${MQTTLIB_C_TARGET} ${MQTTLIB_CS_TARGET} ${MQTTLIB_A_TARGET} ${MQTTLIB_AS_TARGET}
# 同理裁剪安装内容,只安装库和头文件
install: build
mkdir -p $(DESTDIR)$(PREFIX)${includedir}
$(INSTALL_DATA) ${INSTALL_OPTS} ${MQTTLIB_C_TARGET} $(DESTDIR)${libdir}
$(INSTALL_DATA) ${INSTALL_OPTS} ${MQTTLIB_CS_TARGET} $(DESTDIR)${libdir}
$(INSTALL_DATA) ${INSTALL_OPTS} ${MQTTLIB_A_TARGET} $(DESTDIR)${libdir}
$(INSTALL_DATA) ${INSTALL_OPTS} ${MQTTLIB_AS_TARGET} $(DESTDIR)${libdir}
# $(INSTALL_PROGRAM) ${INSTALL_OPTS} ${MQTTVERSION_TARGET} $(DESTDIR)${bindir}
# $(INSTALL_PROGRAM) ${INSTALL_OPTS} ${PAHO_C_PUB_TARGET} $(DESTDIR)${bindir}
# $(INSTALL_PROGRAM) ${INSTALL_OPTS} ${PAHO_C_SUB_TARGET} $(DESTDIR)${bindir}
# $(INSTALL_PROGRAM) ${INSTALL_OPTS} ${PAHO_CS_PUB_TARGET} $(DESTDIR)${bindir}
# $(INSTALL_PROGRAM) ${INSTALL_OPTS} ${PAHO_CS_SUB_TARGET} $(DESTDIR)${bindir}
# $(LDCONFIG) $(DESTDIR)${libdir}
ln -s lib$(MQTTLIB_C).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_C).so
ln -s lib$(MQTTLIB_CS).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_CS).so
ln -s lib$(MQTTLIB_A).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_A).so
ln -s lib$(MQTTLIB_AS).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_AS).so
@if test ! -f $(DESTDIR)${libdir}/lib$(MQTTLIB_C).so.${MAJOR_VERSION}; then ln -s lib$(MQTTLIB_C).so.${VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_C).so.${MAJOR_VERSION}; fi
@if test ! -f $(DESTDIR)${libdir}/lib$(MQTTLIB_CS).so.${MAJOR_VERSION}; then ln -s lib$(MQTTLIB_CS).so.${VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_CS).so.${MAJOR_VERSION}; fi
@if test ! -f $(DESTDIR)${libdir}/lib$(MQTTLIB_A).so.${MAJOR_VERSION}; then ln -s lib$(MQTTLIB_A).so.${VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_A).so.${MAJOR_VERSION}; fi
@if test ! -f $(DESTDIR)${libdir}/lib$(MQTTLIB_AS).so.${MAJOR_VERSION}; then ln -s lib$(MQTTLIB_AS).so.${VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_AS).so.${MAJOR_VERSION}; fi
$(INSTALL_DATA) ${srcdir}/MQTTAsync.h $(DESTDIR)${includedir}
$(INSTALL_DATA) ${srcdir}/MQTTClient.h $(DESTDIR)${includedir}
$(INSTALL_DATA) ${srcdir}/MQTTClientPersistence.h $(DESTDIR)${includedir}
$(INSTALL_DATA) ${srcdir}/MQTTProperties.h $(DESTDIR)${includedir}
$(INSTALL_DATA) ${srcdir}/MQTTReasonCodes.h $(DESTDIR)${includedir}
$(INSTALL_DATA) ${srcdir}/MQTTSubscribeOpts.h $(DESTDIR)${includedir}
$(INSTALL_DATA) ${srcdir}/MQTTExportDeclarations.h $(DESTDIR)${includedir}
# - $(INSTALL_DATA) doc/man/man1/paho_c_pub.1 $(DESTDIR)${man1dir}
# - $(INSTALL_DATA) doc/man/man1/paho_c_sub.1 $(DESTDIR)${man1dir}
# - $(INSTALL_DATA) doc/man/man1/paho_cs_pub.1 $(DESTDIR)${man1dir}
# - $(INSTALL_DATA) doc/man/man1/paho_cs_sub.1 $(DESTDIR)${man1dir}
编译脚本如下:
#!/bin/bash
HOME=$(pwd)
PREFIX_DIR=$HOME/install
COMPILE_HEAD=arm-none-linux-gnueabi-
# export PATH=/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH
make_openssl()
{
cd $HOME
rm -rf openssl-OpenSSL_1_1_1g
tar -zxvf openssl-OpenSSL_1_1_1g.tar.gz
cd openssl-OpenSSL_1_1_1g
make clean
./Configure no-asm shared linux-generic32 --prefix=$PREFIX_DIR --cross-compile-prefix=${COMPILE_HEAD}
make && make install
cd $HOME
rm -rf openssl-OpenSSL_1_1_1g
}
make_paho_mqtt()
{
cd $HOME
rm -rf paho.mqtt.c-v1.3.14
unzip paho.mqtt.c-v1.3.14.zip
cd paho.mqtt.c-v1.3.14
make clean
make CC=${COMPILE_HEAD}gcc LDFLAGS=-L$PREFIX_DIR/lib CFLAGS=-I$PREFIX_DIR/include
make install prefix=$PREFIX_DIR
cd $HOME
rm -rf paho.mqtt.c-v1.3.14
}
make_openssl
make_paho_mqtt
执行结果如下

- libpaho-mqtt3a.so:
- libpaho-mqtt3as.so:
- libpaho-mqtt3c.so:
- libpaho-mqtt3cs.so:
使用cmake方式编译
使用示例
libpaho-mqtt3c.so 使用示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "MQTTClient.h"
#define ADDRESS "mqtt://192.168.1.200:1883"
#define CLIENTID "ExampleClientPub"
#define TOPIC "MQTT Examples"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L
void test_connectionLost(void* context, char* cause)
{
printf("Callback: connection lost\n");
}
void test_deliveryComplete(void* context, MQTTClient_deliveryToken token)
{
printf("Callback: publish complete for token %d\n", token);
}
int test_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *m)
{
// MQTTClient c = (MQTTClient)context;
printf("Callback: message received on topic '%s' is '%.*s'.\n", topicName, m->payloadlen, (char *)(m->payload));
MQTTClient_free(topicName);
MQTTClient_freeMessage(&m);
return 1;
}
int main(int argc, char* argv[])
{
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;
/* 创建MQTT客户端 */
rc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTCLIENT_SUCCESS)
{
printf("Failed to create client, return code %d\n", rc);
exit(EXIT_FAILURE);
}
rc = MQTTClient_setCallbacks(client, (void *)client, test_connectionLost, NULL, test_deliveryComplete);
/* MQTT连接 */
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
/* 订阅主题 */
rc = MQTTClient_subscribe(client, TOPIC, QOS);
if (rc != MQTTCLIENT_SUCCESS)
{
printf("Failed to subscribe, return code %d\n", rc);
rc = EXIT_FAILURE;
}
printf("Subscribing to topic %s for client %s using QoS%d\n\n", TOPIC, CLIENTID, QOS);
/* 发布消息 */
pubmsg.payload = PAYLOAD;
pubmsg.payloadlen = (int)strlen(PAYLOAD);
pubmsg.qos = QOS;
pubmsg.retained = 0;
if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to publish message, return code %d\n", rc);
exit(EXIT_FAILURE);
}
printf("Waiting for up to %d seconds for publication of %s\n"
"on topic %s for client with ClientID: %s\n",
(int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
printf("Message with delivery token %d delivered\n", token);
/* 同步接收消息 */
char *topicName = NULL;
int topicLen = 0;
MQTTClient_message *message = NULL;
while (1)
{
rc = MQTTClient_receive(client, &topicName, &topicLen, &message, 0);
if (message)
{
printf("Message received on topic %s is %.*s.\n", topicName, message->payloadlen, (char*)(message->payload));
MQTTClient_free(topicName);
MQTTClient_freeMessage(&message);
}
sleep(1);
}
/* MQTT断开连接 */
if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS)
printf("Failed to disconnect, return code %d\n", rc);
MQTTClient_destroy(&client);
return rc;
}
libpaho-mqtt3cs.so 使用示例
测试方法
MQTTX:由 EMQ 开发的一款跨平台 MQTT 客户端工具;
EMQX:是一个开源的百万级分布式 MQTT 消息服务器(MQTT Messaging Broker),用于支持各种接入标准 MQTT 协议的设备。
安装与启动 EMQX
- 从 EMQ 官方网站下载适用于操作系统的 EMQX 安装包并解压。
- 启动 EMQX 服务:进入安装目录的 bin 文件夹,在命令行中运行 emqx start 命令。
- 验证服务是否成功启动:通过浏览器访问 http://localhost:18083/,使用默认用户名 admin 和密码 public 登录 EMQX Dashboard 管理控制台 。
安装与配置 MQTTX
- 从官网下载 MQTTX 客户端工具并完成安装。
- 打开 MQTTX 并创建一个新的连接,填写以下信息:
- 名称:为连接设置一个标识名称。
- 客户端 ID:系统会自动生成,也可以手动刷新生成新的 ID。
- 主机地址:通常为 localhost 或指定的服务器 IP 地址。•端口号:如 1883(MQTT 默认端口)或 8083(WebSocket 端口)。
- 点击“连接”按钮,成功后可以在 EMQX Dashboard 中查看新增的连接数。
运行测试程序




浙公网安备 33010602011771号