前后端实现mqtt物联网消息互通对话(图文详解)

news2024/12/22 19:50:39

需求:前端使用mqtt订阅主题和硬件设备进行通讯功能,不走后端,前端操作可以控制。从部署到对话,跟着图文一套下来你也可以学会。很简单的。后端用node,前端就用原生的js,如果要使用vue,可以看我另外一篇:还在写

1.下载EMQX

官网链接:下载 EMQX

步骤如下,我是windows系统就选windows了,看你自己是什么操作系统,根据自己的操作系统进行选择。

 下载好后解压,之后进入到下载的bin目录

控制台输入`emqx start`,注意,此时控制台是没有反应的,就回你个D:\EMQX。其实已经打开了。

 

 2.登录emqx控制台和基本配置图文讲解

 控制台先别关,直接进入EMQX Dashboard,账号admin,密码:public,进行登录后会要求你自己修改密码,想改就改不想改就不改。

 

 点击第四个图标选择监听器可以查看到mqtt的默认监听类型和端口号

 点击第五个图标选择websocket客户端可以看到默认连接的主机名和端口,主题订阅等。

 3.下载node-red

回到之前的控制台,输入

npm install -g node-red

 

 下载完后输入node-red运行

 点击登录node-redNode-RED,输入mqtt

 选择四个节点,并且连接状态如下,连接是手动连接的,上面的hello什么的是配置的,往下看就行了

inject:输入,发消息给客户端

mqtt out:输出

matt in :输入

debug:调试

 4.配置node-red

1.配置mqtt out

注意!!mqtt in 和mqtt out 配置一样就行了

Qos是决定消息质量,Qos:0,是发送端只发送一次,不管服务端收到没,1是至少发送一次,反正服务端一定能收到 1次,有可能收到2次以上,2保证服务端收到且只收到一次,值越大质量越高,qos越小,网络带宽越低。耗能越低

就修改如下俩个就行了,连接本地的1883,之后点击更新按钮,如果没有更新就点完成。

 

 编辑inject节点,选择左边的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()
})

注意这个hellow node js,这个是我订阅了test主题后发送的消息给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>

效果如下:

上面俩个报错,是我浏览器版本过低,vue的扩展插件报错,不用管

 这样就实现了,是不是很简单,文章到此结束,希望对你有所帮助~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/728025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenCV4使用applyColorMap()函数,可以将灰度图或彩色图转换成自定义的彩色图,或opencv提供的20多种色彩值

文章目录 1、applyColorMap()函数的使用&#xff1a;&#xff08;1&#xff09;函数原型&#xff1a;void applyColorMap(InputArray src, OutputArray dst, int colormap)void applyColorMap(InputArray src, OutputArray dst, InputArray userColor) &#xff08;2&#xff0…

记录CompletableFuture使用遇到的坑-多数据源

现象&#xff1a;使用了allof().get()去阻塞线程等待子线程跑完&#xff0c;但子线程还是没跑完就结束了。 代码如图&#xff1a; 如果您熟悉CompletableFuture的.allOf方法应该知道题主是想等3个异步任务完成再往下执行&#xff0c;但事实是3个异步任务执行到最后 "好像…

2023年最新全国分省、市路网数据shp

最新全国分省、市路网数据 2023年 ​ 最近有小伙伴反应无法进入OSM地图官网下载数据&#xff0c;所以这次带来全国路网数据shp文件。获取时间&#xff1a;2023年5月 数据格式&#xff1a;shp 坐标系&#xff1a;GCJ-02 数据概览 分省如下&#xff1a; ​ 例如河北&#xff…

DDR3 控制器 MIG IP 详解完整版 (nativeVIVADOVerilog)

文章目录 前言一、MIG IP 核的配置二、MIG 交互的接口三、常用IP例化值四、小实验传图 前言 本节主要是介绍 Xilinx DDR 控制器 IP 的创建流程、IP 用户使用接口 native 协议介绍和IP 对应的 Example Design 的仿真和上板验证。。 提示&#xff1a;以下是本篇文章正文内容&…

开放式耳机哪个好?综合性能不错的开放式耳机推荐

传统入耳式耳机容易滑落&#xff0c;而且戴久了耳朵疼&#xff0c;开放式耳机的出现就避免了这个问题的出现&#xff0c;本文就为大家推荐几款使用感较好的开放式耳机&#xff0c;一起来看看吧~ 一、NANK南卡OE Pro开放式耳机 南卡OE Pro凭借着顶级的佩戴体验和极高的音质水准…

图像几何变换笔记

图像缩放 图像缩放是指对图像大小进行调整&#xff0c;对原图进行放大或缩小。图像缩放一般通过插值采样来实现。 常见的插值方法&#xff1a;最近邻插值、双线性插值、双三次插值。 最近邻插值 最近邻插值是最简单的一种插值方法&#xff0c;通过映射将原始图片中的像素值映射…

【数据结构与算法】哈希表设计(C\C++)

实践要求 1. 问题描述 针对某个集体中人名设计一个哈希表&#xff0c;使得平均查找长度不超过R&#xff0c;并完成相应的建表和查找程序。 2. 基本要求 假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个&#xff0c;取平均查找长度的上限为2。哈希函数用除留…

C++——string(2)

作者&#xff1a;几冬雪来 时间&#xff1a;2023年7月7日 内容&#xff1a;C——string内容讲解 目录 前言&#xff1a; 1.string&#xff1a; 1. reserve&#xff1a; 2.resize&#xff1a; 3.assign&#xff1a; 4.insert&#xff1a; 5.erase&#xff1a; 6.rep…

策略模式深度实践——通用的HTTP接口调用

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…

【CSS卡片翻转特效】CSS3实现3D旋转动画卡片翻转效果(附源码)

文章目录 写在前面涉及知识点效果展示1、web页面的搭建1&#xff09;创建dom节点2&#xff09;DOM元素添加图片3&#xff09;添加翻转后的文字 2、CSS效果的实现1&#xff09;div本身翻转效果2&#xff09;3D翻转效果完整CSS3实现翻转效果demo代码可以留言邮箱或者自己去百度网…

扒开 TCP 的外衣,看清 TCP 的本质

TCP 非常重要&#xff0c;它的内容很多&#xff0c;今天只能讲解其中的一部分&#xff0c;但足以让你超越 80 % 的编程开发人员对于 TCP 的认知。 本篇内容非常多&#xff0c;非常干&#xff0c;希望你花点时间仔细研究&#xff0c;我相信会对你有所帮助。 1. TCP 协议是什么…

【tomcat】应用服务

准备环境 三台虚拟机 192.168.1.120 192.168.1.122 192.168.1.131 三台虚拟机关闭防火墙 、查看光盘 、检测yun创库 查看JDK是否安装 [rootlocalhost ~]# java -version openjdk version "1.8.0_161" //这是系统自带的rpm方式安装 OpenJDK Runtime Environment…

云端刺点难?这次看看云端地球怎么做

了解像控点与刺点 像控点是直接为摄影测量的控制点加密或测图需要而在实地布设并进行测定的控制点。 刺像控点是把外业采集的像控点的地理坐标与看到这个点的照片相关联的过程。在倾斜摄影建模中&#xff0c;使用像控点进行刺点可以大大提高建模精度。 为什么云端地球可以做…

青岛大学_王卓老师【数据结构与算法】Week04_02_带尾结点的循环链表合并_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c;另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础–…

LLM搭建金融系统

背景&#xff1a; 这篇文章主要给大家介绍如何基于LLM模型配合各种pluging工具&#xff08;这边主要是跟数据连接、检索的工具相关&#xff1a;知识图谱、向量库...)。在开始文章前先讲讲我的观点&#xff1a;大模型的颠覆性应用应该不在于AIGC&#xff0c;而在于数据驱动技术…

python验证公网ip与内网ip

公网IP和内网IP都是用于标识网络设备的地址&#xff0c;但它们有着不同的作用和特点。 公网IP是由互联网服务提供商&#xff08;ISP&#xff09;分配给用户设备的唯一标识符。它是全球范围内唯一的&#xff0c;并且可以被其他网络设备使用来寻找和连接特定的设备。公网IP通常用…

Linux操作系统中命令提示符最后的符号为“#”或“$”

07-Linux操作系统中命令提示符最后的符号为“#”或“$” 1、最后提示符“#”2、最后提示符“$”3、[lwhlocalhost~]中 “ ~” 1、最后提示符“#” 表示管理员身份2、最后提示符“$” 表示不同用户3、[lwhlocalhost~]中 “ ~” 表示当前用户的家目录

安装umi

安装umi 一、安装Node.js&#xff0c;通过node -v查看版本号 二、安装yarn&#xff0c;其中tyarn使用的是npm.taobao.org的源&#xff0c;速度要快一些&#xff08;可以把yarn看做优化了的npm&#xff09; 1. 安装tyarn npm i yarn tyarn -g1 -g&#xff1a;全局安装 2. …

【C++】用Ceres从三维点中拟合三维空间中的圆

任务描述 在三维空间中有N个点&#xff0c;需要得到过这N个点的最优圆&#xff0c;需要估计圆的圆心、半径和法向量&#xff0c;本文提供了一种方法和代码示例&#xff0c;利用Ceres进行非线性拟合&#xff0c;在cpp上开发。 圆心为三维&#xff0c;半径一维&#xff0c;法向…

深入刨析容器(四):深入理解容器镜像

容器通过Namespace和Cgroups将自己与宿主机隔离&#xff0c;那么容器里的进程看到文件系统又是什么样子的呢&#xff1f;容器里的程序应该看到完全独立的文件系统&#xff0c;这样它就可以在自己的容器目录&#xff08;比如 /tmp&#xff09;下进行操作&#xff0c;而完全不会受…