鸟哥杂谈搭建自己的本地mqtt服务器 emqx

Posted 单片机菜鸟哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了鸟哥杂谈搭建自己的本地mqtt服务器 emqx相关的知识,希望对你有一定的参考价值。

忘记过去,超越自己

  • ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️
  • ❤️ 本篇创建记录 2022-10-15 ❤️
  • ❤️ 本篇更新记录 2022-10-15 ❤️
  • 🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝
  • 🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!
  • 🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 🔥

目录

1. 前言

使用多了第三方mqtt服务器(阿里云、OneNet、巴法云等等)之后或者自己写的简单nodejs mqtt服务器之后, 又想看看能否有结合两者的优点的开发方式。

一句话,自己部署一个开源mqtt服务器,集成了绝大部分的功能和管理后台。

而一般在学习物联网中,emqx是提及最多的开源免费mqtt服务器,部署简单。

建议可以看看官方文档。

2. emqx 简介

3. emqx 部署

根据自己的具体操作系统(macOS、Linux、Windows)来下载对应的压缩包。



部署步骤:

4. emqx 运行

要想运行emqx,我们需要先知道有哪些命令行可以用。

官方关于命令行的详细介绍,我们主要先关注启动命令。

4.1 管理员权限执行 emqx start

4.2 浏览器输入 http://localhost:18083/,进入web的控制后台


输入默认账号密码:

  • 账号 admin
  • 密码 public,博哥登录成功之后改为了123456


到这里我们就算是成功运行起了emqx mqtt服务器了。

记住,它是一个mqtt broker

4.3 修改为中文界面


4.4点一下每个页面看看是些什么具体内容。

4.4.1 仪表盘,指标监控

主要是看看整个数据怎么样,订阅数消息流入主题连接等等

4.4.2 连接管理

管理每个连接的一些状态信息,连接以clientid作为一个区分。包括ip地址、心跳等等

4.4.3 mqtt主题,topic相关


包括客户端ID(clientid)、主题(topic)、质量等级(QoS)、遗嘱消息保留消息等等

4.4.4 访问控制,控制用户的访问权限


这里提供了第三方的数据源来做安全校验。比如mysql、redis、http服务器等等。

  • 认证认证只是验证了客户端的身份是否合法,主要看用户是否能登录系统,关联到username和password
    官方文档说明:emqx认证

    EMQX 默认没有限制设备登录认证,而我们实际商用的项目中,安全认证,登录鉴权那是必不可少。我们可以直接使用数据库的sql语句来验证或者连接一个HTTPServer来做。

假设我们通过提供的HTTP服务器来做,那么设备登录认证的流程如下:

  • 设备通过MQTT连接到EMQX
  • EMQX将设备登录上来的username和password通过HTTP POST的方式传递给HTTP Server
  • 认证结果由HTTP Server的返回状态决定EMQX是否建立/拒绝设备的连接。
  • 授权管理指对 MQTT 客户端的发布和订阅操作进行权限控制,控制的内容主要是哪些客户端可以发布或者订阅哪些 MQTT 主题
    官方文档说明:emqx授权管理
  • 黑名单
    官方文档说明:emqx授权管理

4.4.5 数据集成,对接外部系统

数据集成是 EMQX 在发布订阅模型的基础之上的数据处理与分发组件,通过简单的、可视化的配置,即可将消息流以及设备事件与 Kafka、RabbitMQ 等消息中间件,以及各类 SQL / NoSQL / 时序数据库等数据系统集成。

EMQX 通过结合规则与数据桥接两个功能,提供了实时、简洁、高效的数据集成方案。 其中规则用于处理消息或事件,而数据桥接用于对接数据系统。

4.4.6 功能配置

  • 监听器(支持了tcpWebSocket连接,注意它们的端口号 8883/1883/8083/8084
  • mqtt配置(跟mqtt协议相关内容,包括心跳、连接超时、报文最大大小等等)

4.4.7 问题分析,比较有用是日志追踪

5. 接入esp8266 mqtt客户端测试

  • 先获取本地电脑IP地址,使用ipconfig命令

5.1 简单测试功能

  • 把以下代码烧入esp8266 nodemcu,改一下ip、wifi账号密码。
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "TP-LINK_5344";//wifi账号
const char* password = "xxxxx";//wifi秘密
const char* mqtt_server = "192.168.1.104";//mqtt服务器

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() 

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) 
    delay(500);
    Serial.print(".");
  

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());


/**
 * 消息回调
 */
void callback(char* topic, byte* payload, unsigned int length) 
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) 
    Serial.print((char)payload[i]);
  
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') 
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
   else 
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  



/**
 * 断开重连
 */
void reconnect() 
  // Loop until we're reconnected
  while (!client.connected()) 
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) 
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
     else 
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    
  


void setup() 
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  //配置mqtt服务器地址和端口
  client.setServer(mqtt_server, 1883);
  //设置订阅消息回调
  client.setCallback(callback);


void loop() 
  //重连机制
  if (!client.connected()) 
    reconnect();
  
  //不断监听信息
  client.loop();

  long now = millis();
  if (now - lastMsg > 2000) 
    //每2s发布一次信息
    lastMsg = now;
    ++value;
    snprintf (msg, 50, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  

这里我们订阅了主题 inTopic,以及用来发布消息的主题 outTopic

去emqx后台看看。


我们构造一个日志追踪,监听几分钟,然后把日志下载下来。

2022-10-15T14:41:03+08:00 [MQTT] ESP8266Client-7f70@192.168.1.105:65216 msg: mqtt_packet_received, packet: PUBLISH(Q0, R0, D0),Topic=outTopic, PacketId=undefinedPayload=hello world #245
2022-10-15T14:41:03+08:00 [PUBLISH] ESP8266Client-7f70@192.168.1.105:65216 msg: publish_to, topic: outTopic, payload: hello world #245
2022-10-15T14:41:05+08:00 [MQTT] ESP8266Client-7f70@192.168.1.105:65216 msg: mqtt_packet_received, packet: PUBLISH(Q0, R0, D0),Topic=outTopic, PacketId=undefinedPayload=hello world #246
2022-10-15T14:41:05+08:00 [PUBLISH] ESP8266Client-7f70@192.168.1.105:65216 msg: publish_to, topic: outTopic, payload: hello world #246
2022-10-15T14:41:07+08:00 [MQTT] ESP8266Client-7f70@192.168.1.105:65216 msg: mqtt_packet_received, packet: PUBLISH(Q0, R0, D0),Topic=outTopic, PacketId=undefinedPayload=hello world #247
2022-10-15T14:41:07+08:00 [PUBLISH] ESP8266Client-7f70@192.168.1.105:65216 msg: publish_to, topic: outTopic, payload: hello world #247
2022-10-15T14:41:09+08:00 [MQTT] ESP8266Client-7f70@192.168.1.105:65216 msg: mqtt_packet_received, packet: PUBLISH(Q0, R0, D0),Topic=outTopic, PacketId=undefinedPayload=hello world #248
2022-10-15T14:41:09+08:00 [PUBLISH] ESP8266Client-7f70@192.168.1.105:65216 msg: publish_to, topic: outTopic, payload: hello world #248
2022-10-15T14:41:11+08:00 [MQTT] ESP8266Client-7f70@192.168.1.105:65216 msg: mqtt_packet_received, packet: PUBLISH(Q0, R0, D0),Topic=outTopic, PacketId=undefinedPayload=hello world #249
2022-10-15T14:41:11+08:00 [PUBLISH] ESP8266Client-7f70@192.168.1.105:65216 msg: publish_to, topic: outTopic, payload: hello world #249
2022-10-15T14:41:13+08:00 [MQTT] ESP8266Client-7f70@192.168.1.105:65216 msg: mqtt_packet_received, packet: PUBLISH(Q0, R0, D0),Topic=outTopic, PacketId=undefinedPayload=hello world #250
2022-10-15T14:41:13+08:00 [PUBLISH] ESP8266Client-7f70@192.168.1.105:65216 msg: publish_to, topic: outTopic, payload: hello world #250
2022-10-15T14:41:15+08:00 [MQTT] ESP8266Client-7f70@192.168.1.105:65216 msg: mqtt_packet_received, packet: PUBLISH(Q0, R0, D0),Topic=outTopic, PacketId=undefinedPayload=hello world #251
2022-10-15T14:41:15+08:00 [PUBLISH] ESP8266Client-7f70@192.168.1.105:65216 msg: publish_to, topic: outTopic, payload: hello world #251
2022-10-15T14:41:17+08:00 [MQTT] ESP8266Client-7f70@192.168.1.105:65216 msg: mqtt_packet_received, packet: PUBLISH(Q0, R0, D0),Topic=outTopic, PacketId=undefinedPayload=hello world #252
2022-10-15T14:41:17+08:00 [PUBLISH] ESP8266Client-7f70@192.168.1.105:65216 msg: publish_to, topic: outTopic, payload: hello world #252
2022-10-15T14:41:17+08:00 [API] ESP8266Client-7f70@ msg: trace_stopping, 

可以看到日志内容能对接得上我们从 8266发送过来的数据。

5.2 黑名单

把上面的esp8266代码稍微改造一下,使用一个固定的clientid名字。

ESP8266Client-dpjcn


这时候是正常连接的。然后去后台设置一下黑名单看看。

6. 总结

一句话,多看文档多试试,配置起来10分钟即可运行起来。

以上是关于鸟哥杂谈搭建自己的本地mqtt服务器 emqx的主要内容,如果未能解决你的问题,请参考以下文章

ESP 保姆级教程玩转emqx MQTT篇② ——保留消息和遗嘱消息

鸟哥杂谈十分钟搭建自己的本地 Node-Red可拖拽图形化物联网

Centos搭建mqtt

鸟哥杂谈五分钟搭建云服务器 Node-Red,PM2开机启动

鸟哥杂谈十分钟使用命令行在云服务器Centos环境下搭建NodeJS环境

鸟哥杂谈Linux环境搭建Redis