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

  1. 从 EMQ 官方网站下载适用于操作系统的 EMQX 安装包并解压。
  2. 启动 EMQX 服务:进入安装目录的 bin 文件夹,在命令行中运行 emqx start 命令。
  3. 验证服务是否成功启动:通过浏览器访问 http://localhost:18083/,使用默认用户名 admin 和密码 public 登录 EMQX Dashboard 管理控制台 。

安装与配置 MQTTX

  1. 从官网下载 MQTTX 客户端工具并完成安装。
  2. 打开 MQTTX 并创建一个新的连接,填写以下信息:
    • 名称:为连接设置一个标识名称。
    • 客户端 ID:系统会自动生成,也可以手动刷新生成新的 ID。
    • 主机地址:通常为 localhost 或指定的服务器 IP 地址。•端口号:如 1883(MQTT 默认端口)或 8083(WebSocket 端口)。
  3. 点击“连接”按钮,成功后可以在 EMQX Dashboard 中查看新增的连接数。

运行测试程序



posted @ 2025-06-24 16:52  silencehuan  阅读(110)  评论(0)    收藏  举报