フロントエンドとバックエンドで実現するmqtt IoTメッセージ相互通信対話(画像と文章で詳しく解説)

要件: フロントエンドは mqtt を使用してトピックと通信機能のハードウェア デバイスをサブスクライブし、フロントエンドの操作はバックエンドに行かずに制御できます。展開から対話まで、絵と文章に沿って学ぶこともできます。とてもシンプルです。バックエンドはノードを使用し、フロントエンドはネイティブ JS を使用します。vue を使用したい場合は、私の他の記事を参照してください: ( 255 メッセージ) MQTTX を使用してフロントエンドと通信する vue_Please call me Ouhuangi のブログ - CSDN 博客

知らせ!バックエンドのデプロイメントで、WebSocket が使用されておらず、TCP プロトコルが使用されていることが示された場合は、アドレス mqtt://ドメイン名: ポートを提供します。この場合、バックエンドを次のように直接変更する必要があります。 ws://ドメイン名: Port/mqtt に設定すると、接続できるようになります。そうでない場合は、常に接続できないことを示すメッセージが表示されます。これはフロントエンドの問題ではありませんが、バックエンドの設定がないことが原因です。 。

1.EMQXをダウンロードする

公式ウェブサイトのリンク: EMQX をダウンロード

手順は次のとおりです。私は Windows システムを持っているので Windows を選択しますが、お使いのオペレーティング システムに依存しますので、お使いのオペレーティング システムに応じて選択してください。

 ダウンロード後、解凍し、ダウンロードしたbinディレクトリに移動します。

コンソールに「emqx start」と入力します。この時点ではコンソールは応答せず、D:\EMQX が返されることに注意してください。実は、開封されてしまいました。

 

 2. emqx コンソールにログインし、基本的な設定を画像とテキストで説明します

 最初にコンソールを閉じずに、EMQX ダッシュボードに直接入力し、アカウント admin、パスワード: public、ログイン後、自分でパスワードを変更するように求められます。変更したい場合は、変更できます。したくない。

 

 4 番目のアイコンをクリックしてリスナーを選択し、mqtt のデフォルトのリスニング タイプとポート番号を表示します。

 5 番目のアイコンをクリックして WebSocket クライアントを選択すると、デフォルト接続のホスト名とポート、トピックのサブスクリプションなどが表示されます。

 3. ノードレッドをダウンロードする

前のコンソールに戻り、次のように入力します。

npm install -g node-red

 

 ダウンロード後、「node-red」と入力して実行します

クリックして node-red Node-RED にログインし、「mqtt」と入力します

 4 つのノードを選択すると、接続ステータスは次のようになります。接続は手動で接続されており、上記の hello が設定されています。下を見てください。

inject: 入力、クライアントにメッセージを送信

mqtt out: 出力

マットイン:入力

デバッグ: デバッグ

 4. ノードレッドを設定する

1.mqtt outを設定する

知らせ!mqtt in と mqtt out の構成は同じです

Qos はメッセージの品質を決定します。Qos: 0 は、サーバーが受信するかどうかに関係なく、送信者が 1 回だけ送信することを意味します。1 は少なくとも 1 回送信することを意味します。いずれにしても、サーバーは 1 回受信する必要があり、さらに受信することも可能です2 回よりも 2 回の保証 サーバーが受信するのは 1 回のみで、値が大きいほど品質は高く、QOS は小さくなり、ネットワーク帯域幅は低くなります。エネルギー消費量の削減

次の 2 つの点を変更し、ローカル 1883 に接続して、更新ボタンをクリックします。更新がない場合は、完了をクリックします。

 

 注入ノードを編集し、左側の az を選択し、テキスト列を選択し、内容を入力して [完了] をクリックします。

 最後に: 右上隅の「デプロイ」をクリックします。

 

 デバッグ:

 5. EMQX は WebSocket クライアントに接続し、メッセージが受信されたかどうかを確認します。

前の EMQX ページに戻る

クライアントを選択すると、node-red によってデプロイされたクライアントが接続されていることがわかります。

WebSocket クライアント上の接続をクリックし、node-red で設定したトピックをサブスクライブし、node-red からメッセージを送信すると、WebSocket もそれを受信できます。

6. Nodejs はトピックのサブスクリプションを実装し、mqtt にメッセージを送信します。

npm init -y

npm install mqtt

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()
})

この hello ノード js に注目してください。これは、テスト トピックをサブスクライブした後に mqtt サーバーに送信したメッセージです。

 7. フロントエンドはメッセージ送信とサブスクリプションを実装します。

まず、node_modules で mqtt==”dist===” を見つけ、mqtt.min.js をフロントエンド フォルダーにコピーします。

 または使用します

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

完全な接続コードは次のとおりです。

<!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>

効果は次のとおりです。

上記 2 つのエラーは、ブラウザのバージョンが低すぎるためであり、Vue 拡張プラグインがエラーを報告するため、心配する必要はありません。

 これで達成されました。とても簡単ですね。この記事はこれで終わりです。お役に立てば幸いです~

おすすめ

転載: blog.csdn.net/qq_44278289/article/details/131592465