我的手指在终端上颤抖,汗水混着血渍模糊了屏幕。迷雾已经吞没了大半条山路,再晚一点,就彻底找不到回村的方向了。
身后传来窸窣声——是夜行兽,它们嗅到了我的血腥味。我咬牙加快脚步,爬上最后的石坡,信号格终于跳动了一下。快啊……
我输入指令,按下发送。MQTT的数据包像一道微弱的求救电波,在迷雾中挣扎着飞向村庄。
“轰——” 远处,篝火台爆出炽烈的光焰,驱散黑暗。夜行兽嘶叫着退却,而村庄的轮廓,终于清晰。
我瘫倒在地,笑了。

下面用mosquitto实现MQTT,点燃希望的LED
Mosquitto 是一个轻量级的开源 MQTT 代理服务器(MQTT Broker),广泛用于物联网(IoT)通信。
C (使用 libmosquitto)编程可以实现MQTT的各种功能。
创龙资料中以及有相关的MQTT例程,可以很好地帮助我们学习如何开发。
虚拟机如果未安装libmosquitto,可以执行如下:
sudo apt install libmosquitto-dev
下面是一个登录巴法云的实验
#include <stdio.h>
#include <stdbool.h>
#include <getopt.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <libgen.h>
#include <stdint.h>
#include <signal.h>
#include <math.h>
#include <mosquitto.h>
enum Mode{
MQTT_PUBLISH,
MQTT_SUBSCRIBE,
MQTT_INVALID
};
struct _Params {
char host[64];
char topic[64];
char message[128];
int port;
int quality;
enum Mode mode;
};
static const int keepalive = 600;
static int is_connect = false;
static char* g_led="/sys/class/leds/user-led0";
volatile bool g_quit = false;
struct mosquitto *mosq = NULL;
void mqtt_connect_callback(struct mosquitto *mosq, void *obj, int rc)
{
struct _Params *userdata = (struct _Params *)obj;
if (rc == 0) {
is_connect = true;
printf("Connect mqtt broker success (%s:%d).\n", userdata->host, userdata->port);
if (userdata->mode == MQTT_SUBSCRIBE) {
mosquitto_subscribe(mosq, NULL, userdata->topic, userdata->quality);
}
}
}
void mqtt_disconnect_callback(struct mosquitto *mosq, void *obj, int result)
{
struct _Params *userdata = (struct _Params *)obj;
if (userdata->mode == MQTT_SUBSCRIBE) {
printf("disconnect mqtt broker server\n");
}
}
void mqtt_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
char cmd[64] = {0};
printf("recv message: %s\n", (char *)message->payload);
if(strstr(message->payload,"on"))
{
snprintf(cmd, 64, "echo 1 > %s/brightness", g_led);
if (system(cmd) != 0) {
fprintf(stderr, "Error: Failed to turn on %s\n", g_led);
exit(EXIT_FAILURE);
}
}else if(strstr(message->payload,"off"))
{
snprintf(cmd, 64, "echo 0 > %s/brightness", g_led);
if (system(cmd) != 0) {
fprintf(stderr, "Error: Failed to turn on %s\n", g_led);
exit(EXIT_FAILURE);
}
}
}
void sig_handle(int arg)
{
g_quit = true;
mosquitto_disconnect(mosq);
}
int main(int argc, char **argv)
{
struct _Params params;
int ret = -1;
int status = 0;
signal(SIGINT, sig_handle);
ret = mosquitto_lib_init();
if (ret != MOSQ_ERR_SUCCESS) {
printf("mosquitto lib init failed!\n");
exit(-1);
}
strcpy(params.host, "bemfa.com");
params.port=9501;
params.mode=MQTT_SUBSCRIBE;
strcpy(params.topic,"LED002");
mosq = mosquitto_new("这里是CLIENTID", true, ¶ms);
if (mosq == NULL) {
printf("Create new mosquitto client instance failed!\n");
exit(-1);
}
mosquitto_connect_callback_set(mosq, mqtt_connect_callback);
mosquitto_disconnect_callback_set(mosq, mqtt_disconnect_callback);
mosquitto_message_callback_set(mosq, mqtt_message_callback);
ret = mosquitto_connect(mosq, params.host, params.port, keepalive);
if (ret != MOSQ_ERR_SUCCESS) {
printf("mosquitto connect failed!\n");
status = -1;
goto error;
}
mosquitto_loop_forever(mosq, -1, 1);
error:
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return status;
}
没有自己搭建MQTT服务器,利用巴法云

建立一个主题(topic)LED002
1、ctrl+c处理
signal(SIGINT, sig_handle);
void sig_handle(int arg)
{
g_quit = true;
mosquitto_disconnect(mosq);
}
2、mosquitto初始化
ret = mosquitto_lib_init();
if (ret != MOSQ_ERR_SUCCESS) {
printf("mosquitto lib init failed!\n");
exit(-1);
}
3、参数设置
strcpy(params.host, "bemfa.com");
params.port=9501;
params.mode=MQTT_SUBSCRIBE;
strcpy(params.topic,"LED002");
4、新建mosquitto
mosquitto_new的第一个参数是clientid,一般云平台会提供
mosq = mosquitto_new("这里是CLIENTID", true, ¶ms);
if (mosq == NULL) {
printf("Create new mosquitto client instance failed!\n");
exit(-1);
}
5、设置回调处理函数
其中,mqtt_message_callback是收到订阅消息处理,这个用于实现点LED
mosquitto_connect_callback_set(mosq, mqtt_connect_callback);
mosquitto_disconnect_callback_set(mosq, mqtt_disconnect_callback);
mosquitto_message_callback_set(mosq, mqtt_message_callback);
6、mqtt_message_callback订阅消息回调点LED
收到MQTT消息on点LED,收到off熄灭LED
static char* g_led="/sys/class/leds/user-led0";
void mqtt_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
char cmd[64] = {0};
printf("recv message: %s\n", (char *)message->payload);
if(strstr(message->payload,"on"))
{
snprintf(cmd, 64, "echo 1 > %s/brightness", g_led);
if (system(cmd) != 0) {
fprintf(stderr, "Error: Failed to turn on %s\n", g_led);
exit(EXIT_FAILURE);
}
}else if(strstr(message->payload,"off"))
{
snprintf(cmd, 64, "echo 0 > %s/brightness", g_led);
if (system(cmd) != 0) {
fprintf(stderr, "Error: Failed to turn on %s\n", g_led);
exit(EXIT_FAILURE);
}
}
}
7、链接MQTT服务器等待订阅消息
ret = mosquitto_connect(mosq, params.host, params.port, keepalive);
if (ret != MOSQ_ERR_SUCCESS) {
printf("mosquitto connect failed!\n");
status = -1;
goto error;
}
mosquitto_loop_forever(mosq, -1, 1);