在实现了 MQTTClient 库与不同平台相关的代码之后,《实现ESP8266模块的socket接口,以提供MQTTClient库底层数据收发接口》这篇文章有介绍。就可以编写 MQTTClient 例程进行实际的网络连接,以及使用 MQTT 协议发布/订阅消息了。

1. MQTTClient测试程序

我使用的 MQTT 函数库到这里下载:

https://github.com/jiejieTop/mqttclient

根据里面的测试示例程序,编写适配我自己设备的程序,代码如下:

void mqtt_client_test(void *parameter)
{
	int result = 0;
	char buf[32];
	int cnt = 0;
	
    mqtt_client_t *client = NULL;
    mqtt_message_t msg;

    memset(&msg, 0, sizeof(msg));

    mqtt_log_init();

    client = mqtt_lease();
	
    mqtt_set_port(client, "1883");

    mqtt_set_host(client, "192.168.0.103"); 			// 电脑的IP地址
    mqtt_set_client_id(client, random_string(10));
    mqtt_set_user_name(client, random_string(10));
    mqtt_set_password(client, random_string(10));
    mqtt_set_clean_session(client, 1);
	
    /* 连接 MQTT Server */
    if (0 != mqtt_connect(client))
    {
		printf("mqtt_connect error\r\n");
		vTaskDelete(NULL);
    }
	
    /**
     * 订阅主题为 topic1 的消息,如果 MQTT Server 发布了这个主题的消息,那么设备就会
     * 收到这条消息,并且还会运行这条消息对应的处理函数 topic1_handler
     */
    result = mqtt_subscribe(client, "topic1", QOS0, topic1_handler);
	if (result)
	{
		printf("mqtt_subscribe topic1 error\r\n");
	}

    msg.payload = buf;
    msg.qos = QOS0;

    while (1) 
    {
		sprintf(buf, "mqtt_test, %d", cnt++);
        msg.payloadlen = strlen(msg.payload);
		mqtt_publish(client, "mqtt_publish", &msg);		// MQTT Client 发布主题为 mqtt_publish 的消息给 MQTT Server
        vTaskDelay(2000);
    }
}

编写完成之后,我们需要创建一个 MQTT Client 测试任务,我这里使用的系统是 FreeRTOS 。

我使用CubeMX生成的 FreeRTOS 项目工程,他会生成一个 freertos.c 文件,里面有一个 FreeRTOS 初始化函数,我们需要在里面创建两个任务,一个是 at_recv_parser 任务,这个任务是一直阻塞等待接收 ESP8266 模块通过串口发送过来的数据,并且对数据进行解析后提供给其他的任务使用。另一个任务就是 mqtt_client_test 任务,即 MQTTClient 测试任务,里面负责发布或者订阅消息。

/* 任务属性 */
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 512 * 4
};

void MX_FREERTOS_Init(void) 
{
    osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);   // CubeMX自动生成的一个默认任务
    osThreadNew(mqtt_client_test, NULL, &defaultTask_attributes);   // MQTTClient测试任务
    osThreadNew(at_recv_parser, NULL, &defaultTask_attributes);		// AT命令解析任务
}

2. 测试过程

编写好上面的代码之后,就可以编译下载到开发板上进行测试了,我使用的是 STM32F407 芯片进行测试。

2.1 在PC上安装两个应用程序

需要在PC端安装一个 MQTT Server 程序(接收开发板的连接),和一个 MQTT Client 程序(发布或者订阅开发板的消息)。

java MQTT服务端 客户端 mqtt客户端编写_java MQTT服务端 客户端

  • mosquitto-2.0.14-install-windows-x64 :是在 PC 上运行的 MQTT Server 程序,这个应用程序在后面的实验中是需要一直运行的。
  • MQTTX-Setup-1.7.2-x64 :图形化 MQTT Client 桌面程序,可以订阅和发布消息。

2.2 修改 mosquitto 配置文件

安装好了这个 MQTT Server 程序之后,默认只支持电脑上的回环测试IP的(127.0.0.1),我们需要支持我们自己电脑的 IP 的话,那需要修改安装目录下的配置文件 mosquitto.conf

  • 在232行设置默认的监听端口为1883,去 ‘#’ 掉注释符号即可。
  • 在529行,改为允许异步接收,即更改为 true 。
  • java MQTT服务端 客户端 mqtt客户端编写_MQTT_02

2.2 启动 mosquitto 服务程序

该程序默认安装在,c:\Program Files\mosquitto 这个目录下,我们需要启动命令行,然后进入到这个目录下启动这个程序。

cd  "c:\Program Files\mosquitto"			# 进入目录
.\mosquitto.exe -c mosquitto.conf -v		# 启动MQTT服务程序

java MQTT服务端 客户端 mqtt客户端编写_网络_03

下面进行的实验中,都要保持 MQTTServer 程序移植在运行。

2.3 MQTTX 程序去连接 mosquitto

  • 打开 MQTTX 程序,建立一个连接。

    连接之后,命令行 mosquitto 那边会提示连接成功。
  • 订阅 mqtt_publish 主题,因为代码里面写的就是发布这个主题消息的。所以电脑上运行的客户端订阅这个主题。

3. 开发板运行MQTTClient程序,实现通信过程

下载程序到开发板运行,当程序运行起来后,就会去连接电脑上运行的 mosquitto MQTT服务程序。这个时候,开发板不断发布主题 mqtt_publish 的消息,而有因为 MQTTX 订阅了这个主题,所以 服务器会转发这个主题消息到 MQTTX 上。如下:

java MQTT服务端 客户端 mqtt客户端编写_网络_04

这个实际的通信过程其实就是,开发板就是我们的设备,而 MQTTX 是电脑上运行的一个 MQTT 客户端程序,这个程序也可以在手机上运行等等。 mosquitto MQTT服务程序在这个过程中充当消息转发而已。大致通信过程如下:

java MQTT服务端 客户端 mqtt客户端编写_MQTT_05


通过上述过程,这样我们就可以通过手机远程去控制我们的设备,或者我们的远程设备上报数据到手机上面了。

完整的工程代码可以去下面的链接下载。