搭建springboot和Vue页面之间的MQTT通信

1.首先在一台准备好的Linux服务器安装EMQX,作为MQTT服务器
1.wget https://www.emqx.com/zh/downloads/broker/5.0.21/emqx-5.0.21-el8-amd64.tar.gz
2.mkdir -p emqx && tar -zxvf emqx-5.0.21-el8-amd64.tar.gz -C emqx
3.启动 EMQX
./emqx/bin/emqx start
放行端口:
18083(mqtt后台端口 )
8083(mqtt的websocket连接端口 )
1883(mqtt的TCP连接端口 )
2.访问EMQX客户端:服务器IP:18083,如果出现如下页面,说明安装成功

初始账号:admin
初始密码:public
登录进去会提示修改密码,将密码改成自己的即可

在这里插入图片描述

springboot项目引入MQTT

一、引入依赖

 <!--MQTT协议依赖-->
 <dependency>
     <groupId>org.eclipse.paho</groupId>
     <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
     <version>1.2.0</version>
 </dependency>
 <!-- https://mvnrepository.com/artifact/org.springframework.integration/spring-integration-mqtt -->
 <dependency>
     <groupId>org.springframework.integration</groupId>
     <artifactId>spring-integration-mqtt</artifactId>
     <version>5.4.3</version>
 </dependency>

二、新建类:MyMqttServer.java(初始化mqtt,发布和订阅主题的类)

package com.system.mqttMessage;

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;

import java.util.*;

/**
 * @author wangghua
 * @ClassName MyMqttClient
 * @描述:
 * @datetime 2023年 4月 28日 14:34
 */
@Async
public class MyMqttServer {
    private static final Logger logger = LoggerFactory.getLogger(MyMqttServer.class);
    public static MqttClient mqttClient = null;
    private static MemoryPersistence memoryPersistence = null;
    private static MqttConnectOptions mqttConnectOptions = null;
    private static String clientId = "serviceId:20230428123456789";
    private static String mqttuser = "admin";
    private static String password = "你修改的密码";
    private static String Host = "tcp://服务器IP:1883";
    /**
     * 保存topic,断开重连,重新订阅
     */
    private static Set<String> topicSet = new HashSet<>();

    /**
     * 初始化客户端,连接mqtt服务器
     */
    public static void init() {
        memoryPersistence = new MemoryPersistence();
        try {
            mqttClient = new MqttClient(Host, clientId, memoryPersistence);
        } catch (MqttException e) {
            e.printStackTrace();
        }
        mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setCleanSession(false);
        mqttConnectOptions.setConnectionTimeout(30);
        mqttConnectOptions.setKeepAliveInterval(45);
        //设置自动重连
        mqttConnectOptions.setAutomaticReconnect(true);
        //下面两个存在就加上
        mqttConnectOptions.setUserName(mqttuser);
        mqttConnectOptions.setPassword(password.toCharArray());
        if (!mqttClient.isConnected()) {
            try {
                mqttClient.connect(mqttConnectOptions);
                mqttClient.setCallback(new PublishCallBack());
                logger.info("mqtt 连接成功!");
            } catch (MqttException e) {
                e.printStackTrace();
            }
        } else {
            logger.info("mqttClient is error");
        }
    }

    /**
     * 断开重连,重新订阅之前的topic,60秒重试一次
     */
    public synchronized static void reConnect() {
        while (true) {
            if (null != mqttClient) {
                if (!mqttClient.isConnected()) {
                    if (null != mqttConnectOptions) {
                        try {
                            mqttClient.connect(mqttConnectOptions);
                            mqttClient.setCallback(new PublishCallBack());
                        } catch (MqttException e) {
                            e.printStackTrace();
                        }
                        if (mqttClient.isConnected()) {
                            String[] topicArr = new String[topicSet.size()];
                            topicSet.toArray(topicArr);
                            logger.info("主题列表:{}", topicArr);
                            subTopic(topicArr);
                            break;
                        }
                    } else {
                        logger.info("mqttConnectOptions is null");
                    }
                } else {
                    logger.info("mqttClient is null or connect");
                }
            } else {
                init();
            }
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                System.out.println("断开重连错误信息:"+e.getMessage());
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭连接
     */
    public static void closeConnect() {
        //关闭存储方式
        if (null != memoryPersistence) {
            try {
                memoryPersistence.close();
                topicSet.clear();
            } catch (MqttPersistenceException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            logger.info("memoryPersistence is null");
        }

//		关闭连接
        if (null != mqttClient) {
            if (mqttClient.isConnected()) {
                try {
                    mqttClient.disconnect();
                    mqttClient.close();
                } catch (MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else {
                System.out.println("mqttClient is not connect");
            }
        } else {
            System.out.println("mqttClient is null");
        }
    }

    //	订阅主题
    public static void subTopic(String[] topicArr) {
        System.out.println("订阅主题 = " + Arrays.deepToString(topicArr));
        for (String topic : topicArr) {
            topicSet.add(topic);
        }
        if (null != mqttClient && mqttClient.isConnected()) {
            try {
                mqttClient.subscribe(topicArr);
            } catch (MqttException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            logger.info("mqttClient is error");
        }
    }


    /**
     * 清空主题
     *
     * @param topic
     */
    public static void cleanTopic(String topic) {
        if (null != mqttClient && !mqttClient.isConnected()) {
            try {
                mqttClient.unsubscribe(topic);
                topicSet.remove(topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        } else {
            logger.info("mqttClient is error,Maybe the MQTT connection is down....");
        }
    }

    /**
     * 发布消息
     * @param pubTopic
     * @param message
     */
    public static void publishMessage(String pubTopic, String message) {
        //打开连接
        MyMqttServer.init();
        if (null != mqttClient && mqttClient.isConnected()) {
            MqttMessage mqttMessage = new MqttMessage();
            mqttMessage.setQos(2);
            mqttMessage.setPayload(message.getBytes());
            MqttTopic topic = mqttClient.getTopic(pubTopic);
            if (null != topic) {
                try {
                    MqttDeliveryToken publish = topic.publish(mqttMessage);
                    if (!publish.isComplete()) {
                        logger.info("mqtt消息发布成功");
                    }
                } catch (MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        } else {
            MyMqttServer.reConnect();
        }
        //关闭连接
        MyMqttServer.closeConnect();
    }


}

三、新建类:PublishCallBack.java(处理收到的消息)

package com.system.mqttMessage;

import com.alibaba.fastjson.JSONObject;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author wangghua
 * @ClassName PublishCallBack
 * @描述:
 * @datetime 2023年 4月 28日 14:37
 */
public class PublishCallBack implements MqttCallback {
    private static final Logger logger = LoggerFactory.getLogger(PublishCallBack.class);


    public void connectionLost(Throwable throwable) {
        logger.info("断开连接,正在准备重连");
        throwable.printStackTrace();
        MyMqttServer.reConnect();
    }

    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        //subscribe后会执行到这里
        System.out.println("消息的主题是:"+topic);
        System.out.println("消息的Qos是:"+mqttMessage.getQos());
        System.out.println("消息的ID是:"+mqttMessage.getId());
        String message = new String(mqttMessage.getPayload());
        JSONObject jsonObject = JSONObject.parseObject(message);
        System.out.println("消息的内容是:"+message);
        System.out.println("转化的jsonObject消息的内容是:"+jsonObject);
    }

    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        //publish可以执行到这里
        System.out.println("This is deliveryComplete method----->"+iMqttDeliveryToken.isComplete());
    }
}

三、增加发布消息的接口

package com.system.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jodd.util.StringUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import springfox.documentation.annotations.ApiIgnore;
import java.util.Date;
import java.util.List;

@ApiIgnore
@Controller
@RequestMapping("/api/msg")
@Api(tags = "Websocket")
public class WebsocketController {


	public @ResponseBody
	@GettMapping("/sendWebsocketMsg")
    @ApiOperation("消息发送")
    String  sendWebsocketMsg(String data,String topic){
        MyMqttServer.publishMessage(topic,data);
		return "发送成功";
	}

}

这是发布成功的控制台打印
在这里插入图片描述

Vue引入MQTT

一、下载依赖

npm install mqtt --save

二、完整代码

<template>
  <div class="hello">
    <h1>收到的消息:{{myMsg}}</h1>
    <el-input
          v-model="sendMessage"
          placeholder="请输入需要发送的消息"
          clearable
        />
    <button @click="mqttPublish">发送</button>
  </div>
</template>

<script>
import mqtt from "mqtt";
export default {
  name: "HelloWorld",
  data() {
    return {
        client: "",
      	sendMessage: "",
      	myMsg:"",
      	topicMqtt:"messageTopic"
    };
  },
 destroyed: function() {
    //页面销毁时关闭长连接
    // this.websocketclose();
    if (this.client.end) this.client.end();
  },
  mounted() {
    this.initMqtt();
    this.mqttReceive();
  },
  methods: {
    /**
     * @name:初始化mqtt
     * @msg:
     * @param {*}
     * @return {*}
     */
    initMqtt() {
    
      let vm = this;
       let commonApi = "ws://服务器IP:8083/mqtt";
      var mqtt = require("mqtt");
      var options = {
        //mqtt客户端的id
        clientId: "system-"+ Math.random().toString(16).substr(2, 8),
      };
      vm.client = mqtt.connect(commonApi, options);
      this.client.on("connect", function () {
        console.log("连接成功....");
      });
      //如果连接错误,打印错误
      vm.client.on("error", function (err) {
        console.log("err=>", err);
        vm.client.end();
      });
    },
    /**
     * @name:发布mqtt消息
     * @msg:
     * @param {*}
     * @return {*}
     */
    mqttPublish() {
      this.client.publish(this.topicMqtt, JSON.stringify(this.sendMessage));
    },
    /**
     * @name:接收mqtt消息
     * @msg:
     * @param {*}
     * @return {*}
     */
    mqttReceive() {
      const vm = this;
      vm.client.subscribe(vm.topicMqtt,{ qos: 1 }, function (err) {
        if (!err) {
          console.log("subscribe success!");
        } else {
          //打印错误
          console.log("err", err);
        }
      });
      vm.client.on("message", function (topic, message) {
      	vm.myMsg = message.toString();
        console.log('收到来自',topic,'的信息',message.toString())
        vm.$notify({
          title: '新消息通知',
          message: message.toString(),
          dangerouslyUseHTMLString: true,
          // position: 'bottom-right',
          duration: 0,//0为手动关闭消息提示
          type: 'warning',
        });
      });
    },
   
  },
};
</script>
页面收到消息截图

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
搭建Spring BootVue前后端分离项目需要以下步骤: 1. 安装环境:首先,需要安装Java JDK和Maven来支持Spring Boot的开发。可以去官方网站下载并安装。然后,安装Node.js和Vue CLI来支持Vue的开发。 2. 创建Spring Boot项目:使用Maven创建一个Spring Boot的项目,可以使用宝塔面板自带的Maven插件进行构建,也可以通过命令行进入项目目录,运行`mvn clean install`来创建项目。 3. 编写后端代码:在Spring Boot项目中编写后端逻辑,包括接口的实现、数据库的操作等。可以选择使用Spring Data JPA来简化对数据库的操作。 4. 创建Vue项目:使用Vue CLI创建一个Vue项目,可以通过宝塔面板自带的Node.js插件进行创建,也可以通过命令行运行`vue create 项目名`来创建。 5. 编写前端代码:在Vue项目中编写前端逻辑,包括页面的布局、调用后台接口等。可以使用axios库来发送HTTP请求。 6. 配置跨域:由于前后端分离的项目可能存在不同端口的情况,需要进行跨域配置。可以在Spring Boot项目的配置文件中添加`@CrossOrigin`注解,允许指定的域访问接口。 7. 打包部署:完成开发后,可以使用Maven将后端项目打包成一个独立的Jar文件。然后,将打包好的Jar文件上传到宝塔面板上的对应目录。将Vue项目使用`npm run build`命令打包成静态文件,然后将打包好的文件上传到宝塔面板对应的目录。 8. 配置Nginx反向代理:为了将前后端项目结合在一起,可以使用Nginx配置反向代理,将前端的请求转发给后端的接口。在宝塔面板上找到对应的站点,进行Nginx配置。 通过以上步骤,就可以搭建一个基于Spring BootVue的前后端分离项目,并将项目部署到宝塔面板上进行访问和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值