2-6 保护 Mosquitto

ESP8266 家庭自动化项目中文版目录​​​​​​​

如果您的 Mosquitto MQTT 代理在云端,最好至少使用用户和密码来保护它。
Mosquitto 提供了 mosquitto_passwd 实用程序,它允许我们创建用户和密码。系统将邀请您输入密码并进行确认:

sudo mosquito_passwd -c  /etc/mosquito/passwd  
joe

/etc/mosquitto 目录中,将创建一个名为 passwd 的文件,该文件将是一个名为 joe 的用户及其编码过的密码,如下面的屏幕截图所示:

现在让我们将 passwd 文件添加到 mosquitto.conf 文件中。使用您喜欢的文本编辑器并更改 file/etc/mosquitto.conf 以指示Mosquitto 读取和使用 passwd 文件。文件的内容将是:

Password fle location
  • allow_anonymous:这是一个布尔值,用于确定是否允许不提供用户名的客户端进行连接。如果设置为false,则还意味着一个去控制经过身份验证的客户端访问的连接应该被创建。
  • password_file:设置密码文件的路径。如果已定义,则文件的内容用于控制客户端对代理的访问。如果 allow_anonymous 设置为false,则只有此文件中定义的用户才能连接。

使用以下命令停止并重新启动Mosquitto服务后:

sudo service mosquitto stop && sudo service mosquitto start

如果终端窗口将尝试像以前一样进行连接,我们将收到一条错误消息,如以下屏幕截图所示:

但是,使用前面创建的用户和密码进行订阅和发布将可以正常工作。对于订阅命令是:

sudo mosquitto_sub -t living/temperature -u
joe -P joe1234

发布消息的命令

sudo mosquitto_pub -t living/temperature -u
joe -P joe1234 -m {"t":24.7}

确保使用大写字母 P 代表密码,而不是代表端口的小写 p ,你将获得以下结果:

Providing username and password 

现在让我们使用ESP8266向代理发送用户名和密码:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

使用适合您网络的值更新这些值:

const char* wifi_network = "WiFi 176-58";
const char* password = "P6etRUzaRa";
const char* mqtt_serv_address = "192.168.1.116";
const char* mqtt_user = "joe";
const char* mqtt_passwd = "joe1234";
const int mqtt_port_number = 1883;
#define OUTDOOR LIGHT 12

mqtt_user 将保存用户名的值,mqtt_passwd 将保存用户的密码。
我们将在 connect 方法中使用它们并将它们传递给服务器:

WiFiClient espClient; 
PubSubClient client(espClient);
long lastMsg = 0;

void setup() {
  pinMode (OUTDOOR_LIGHT, OUTPUT);
  // 初始化BUILTIN LED引脚作为输出
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_serv_address, mqtt_port_number);
  client.setCallback(callback);
}

void setup_wifi() {
  delay(10);
  //我们首先连接到WiFi网络
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_network);
  WiFi.begin(ssid, password);
  while(WiFi.status()!=WL_CONNECTED){
    WiFi.begin(wifi_network, password);
    Serial.print(".");
    delay(5000);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int msg_length) {
  Serial.print("Message arrived [" );
  Serial.print(topic);
  Serial.print("] " );
  for (int i = O; i< msg_length; i++) {
    Serial.print((char)payload[i]);
    Serial.println();
    //如果收到的第一个字符为1,则打开LED
    if ((char)payload[O] == '0') {
      digitalWrite(OUTDOOR_LIGHT, LOW); // 关闭LED
    } else {
      digitalWrite(OUTDOOR_LIGHT, HIGH); // 打开LED
    }
  }
}

void reconnect() {
  //循环直到我们重新连接
  while (!client.connected()){
    Serial.print("Attempting MQTT connection. . .");

尝试使用 mqtt_usermqtt_passwd 中的用户名和密码连接到 MQTT  Mosquitto 代理:

    if (client.connect("ESP8266Client",mqtt_user ,mqtt_passwd)){
      Serial.println("connected");
      client. subscribe ("outdoor/light");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // 等待5秒再重试
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now; .
    String light_state;
    if (digitalRead(OUTDOOR_LIGHT) == HIGH)
      light_state = "ON";
    else
      light_state = "OFF";
    Serial.print("Publish message:");
    Serial.println(light_state);
    client.publish("outdoor/light/status" , light_state.c_str());
  }
}

发布有效负载为 1 的消息将触发 GPIO 12 并以安全的方式打开连接的LED。 ON、OFF 消息是 GPIO 的状态,其中ON为 3V3 ,OFF为 0V:

接收ON / OFF消息

现在,从世界上任何地方发送此消息将打开和关闭您家中的任何设备,如果不是LED,我们将添加一个继电器板:

提示:到目前为止,使用了小消息,默认情况下,PubSubClient 允许的最大大小为128字节。如果消息大于128个字节,请转到PubSubClient.h文件并更改MQTT MAX PACKET SIZE的值。

猜你喜欢

转载自blog.csdn.net/countofdane/article/details/86741945
2-6