Front and back ends realize mqtt Internet of things message intercommunication dialogue (detailed explanation with pictures and texts)

Requirements: The front-end uses mqtt to subscribe topics and hardware devices for communication functions, and the front-end operations can be controlled without going to the back-end. From deployment to dialogue, you can also learn by following the set of pictures and texts. Very simple. The backend uses node, and the frontend uses native js. If you want to use vue, you can read my other article: (255 messages) Use MQTTX to communicate with the frontend vue_Please call me Ouhuangi's blog-CSDN博客

Notice! ! ! ! ! If the back-end deployment tells you that websocket is not used, and the tcp protocol is used, I will give you an address mqtt://domain name: port. In this case, you need to change the back-end directly to ws://domain name: Port/mqtt, so that you can connect, otherwise you will always be prompted that you cannot connect, and it is not a problem with the front end, but it is caused by no configuration in the back end.

1. Download EMQX

Official website link: Download EMQX

The steps are as follows. I choose windows because I have a windows system. It depends on your own operating system and chooses according to your own operating system.

 After downloading, unzip it, and then enter the downloaded bin directory

Enter `emqx start` in the console. Note that the console does not respond at this time, and it will return you D:\EMQX. In fact, it has been opened.

 

 2. Log in to the emqx console and explain the basic configuration with pictures and texts

 Don’t close the console first, directly enter the EMQX Dashboard , account admin, password: public, after logging in, you will be asked to change the password yourself, if you want to change it, you can change it if you don’t want to.

 

 Click the fourth icon to select the listener to view the default listening type and port number of mqtt

 Click the fifth icon to select the websocket client to see the host name and port of the default connection, topic subscription, etc.

 3. Download node-red

Back to the previous console, enter

npm install -g node-red

 

 After downloading, enter node-red to run

 Click to log in node-red Node-RED , enter mqtt

 Select four nodes, and the connection status is as follows, the connection is manually connected, the hello above is configured, just look down

inject: input, send a message to the client

mqtt out: output

matt in : input

debug: debug

 4. Configure node-red

1. Configure mqtt out

Notice! ! The mqtt in and mqtt out configurations are the same

Qos determines the quality of the message. Qos: 0 means that the sender only sends once, regardless of whether the server receives it or not. 1 means at least once. Anyway, the server must receive once, and it is possible to receive more than 2 times. 2 guarantees The server receives it only once, the larger the value, the higher the quality, the smaller the qos, and the lower the network bandwidth. lower energy consumption

Just modify the following two things, connect to the local 1883, and then click the update button, if there is no update, click finish.

 

 Edit the inject node, select az on the left, select the text column, enter the content and click Finish

 Finally: Click Deploy in the upper right corner

 

 debugging:

 5. EMQX connects to the websocket client to check whether the message is received

Back to the previous EMQX page

Select the client, and you can see that a client has been connected, which is deployed by node-red

Click on the connection on the websocket client, then subscribe to the topic I set in node-red, send a message from node-red, and websocket can also receive it.

6. Nodejs implements topic subscription and sends messages to mqtt

npm init -y

npm install mqtt

Create index.js

const mqtt = require('mqtt')
const client  = mqtt.connect('mqtt://localhost')

client.on('connect', function () {
  client.subscribe('/test', function (err) {
    if (!err) {
      client.publish('/test', 'Hello node js')
    }
  })
})

client.on('message', function (topic, message) {
  // message is Buffer
  console.log(message.toString())
  client.end()
})

Pay attention to this hellow node js, this is the message I sent to the mqtt server after subscribing to the test topic

 7. The front end implements message sending and subscription

First find mqtt==”dist===” under node_modules and copy mqtt.min.js to the front-end folder

 or use

    <script src="https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js"></script>

The complete connection code is as follows

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/mqtt/4.1.0/mqtt.min.js"></script>
  </head>
  <body>
    <form onsubmit="return false">
        <h3>WebSocket 聊天室:</h3>
        <textarea
          id="textarea"
          style="width: 500px; height: 300px"
        ></textarea>
        <br />
        <input type="text" id="myInput" />
        <button onclick="handleClick()">点击获取输入框的值发送</button>
        <input
          type="button"
          value="清空聊天记录"
          onclick="javascript:document.getElementById('myInput').value=''"
        />
        <button onclick="closeWeb()">关闭客户端连接</button>
      </form>

    <script>
      // 连接地址,有很多连接失败都是因为地址没写对
      const connectUrl = `ws://localhost:8083/mqtt`;
      // 客户端ID 随机数以免重复
    //   const clientId = `mqtt_${Math.random().toString(16).slice(3)}`;
    //   const clientId = `mqttx_a16dc275`;
    //   console.log("客户端id:" + clientId);

      // 连接设置
      let options = {
        clean: true, // 保留会话
        connectTimeout: 4000, // 超时时间
        reconnectPeriod: 1000, // 重连时间间隔
        // 认证信息
        // clientId,
        // username: "root3",
        // password: "123456",
      };
      // 需要订阅的主题
      const topic = "esp8266";
      const topic1 = "/test";

      // 创建客户端
    //   var client = mqtt.connect(connectUrl, options);
    var client =mqtt.connect('ws://localhost:8083/mqtt');

      // 成功连接后触发的回调
      client.on("connect", () => {
        $("#ts").html("在线");
        console.log("已经连接成功");
        // 订阅主题,这里可以订阅多个主题
        client.subscribe([topic, topic1], () => {
          console.log(`订阅了主题 ${[topic, topic1].join("和")}`);
        });
      });

      // 当客户端收到一个发布过来的消息时触发回调
      /**
       * topic:收到的报文的topic
       * message:收到的数据包的负载playload
       * packet:MQTT 报文信息,其中包含 QoS、retain 等信息
       */
      client.on("message", function (topic, message, packet) {
        // 这里有可能拿到的数据格式是Uint8Array格式,可以直接用toString转成字符串
        // let data = JSON.parse(message.toString());
        console.log("获取到的数据:", message);
        console.log("数据对应订阅主题:", topic);
        var ta =document.getElementById("textarea")
        ta.value=ta.value + "\n" + message;
        // var message_packet = JSON.parse(Uint8ArrayToString(packet.payload));
        // console.log("获取到的数据包:", message_packet);
        // message_packet.msg;
      });

      // 当重新连接启动触发回调
      client.on("reconnect", () => {
        $("#ts").html("重连");
        console.log("正在重新连接");
      });

      // 连接断开后触发的回调
      client.on("close", function () {
        $("#ts").html("离线");
        console.log("已断开连接");
      });

      // 在收到 Broker(消息服务器) 发送过来的断开连接的报文时触发的回调,参数 packet 即为断开连接时接收到的报文。MQTT 5.0特性
      client.on("disconnect", function (packet) {
        console.log("从broker接收到断开连接的报文:" + packet);
      });

      // 客户端脱机下线触发回调
      client.on("offline", function () {
        console.log("您已断开连接,请检查网络");
      });

      // 当客户端无法成功连接时或发生解析错误时触发的回调,参数 error 为错误信息
      client.on("error", (error) => {
        console.log("客户端出现错误:", error);
      });

      //当客户端发送任何数据包时发出。这包括publish()以及MQTT用于管理订阅和连接的包
      client.on("packetsend", (packet) => {
        console.log("客户端已发出报文", packet);
      });

      //当客户端接收到任何报文时发出。这包括来自订阅主题的信息包以及MQTT用于管理订阅和连接的信息
      client.on("packetreceive", (packet) => {
        // 会在 client.on('message', function (topic, message, packet) {}); 之前触发
        console.log("客户端接收报文", packet);
      });

      // 关闭客户端(断开连接)
      //client.end();

      // 发送信息给 topic(主题)
      //client.publish(topic, '这是给topic发送的信息');

      //var topic_data=[];
      //topic_data.push(map)
      function Uint8ArrayToString(fileData) {
        var dataString = "";
        for (var i = 0; i < fileData.length; i++) {
          dataString += String.fromCharCode(fileData[i]);
        }
        return dataString;
      }
      function handleClick(){
        var inputElement = document.getElementById("myInput");
        var value = inputElement.value;
        console.log(value,'获取到的值');
        if(value != "" && value !=null){
            // 发送信息给 topic1
            client.publish(topic1, value);
            var ta =document.getElementById("textarea")
            // ta.value+=value;
            
        }else{
            alert("请填写内容")
        }
      }
      function closeWeb(){
              client.end();
      }
    </script>
  </body>
</html>

The effect is as follows:

The above two errors are because my browser version is too low, and the Vue extension plug-in reports an error, so don’t worry about it

 This is achieved, isn’t it very simple, this is the end of the article, I hope it can help you~

Guess you like

Origin blog.csdn.net/qq_44278289/article/details/131592465