马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
先下载依赖- npx --yes --registry https://registry.npmmirror.com npm install mqtt
复制代码 在src的api创建 mes.js- // 导入axios
- import axios from 'axios';
- // 定义一个变量,记录公共的前缀, baseURL
- const baseURL = 'http://localhost:8080';
- const instance = axios.create({ baseURL });
- // 添加响应拦截器
- instance.interceptors.response.use(
- (response) => {
- return response.data; // 直接返回响应的数据部分
- },
- (error) => {
- alert('服务异常');
- return Promise.reject(error); // 异步的状态转化成失败的状态
- }
- );
- // 定义 meslist 函数,使用定制的 Axios 实例发送请求
- export const meslist = async (topic) => {
- try {
- const response = await instance.get('/getmes', {
- params: {
- topic: topic
- }
- });
- return response; // 返回整个响应对象,因为拦截器已经提取了 data 部分
- } catch (error) {
- console.error('API 请求失败:', error);
- throw error;
- }
- };
- export default instance;
复制代码 创建一个vue文件,然后填自己的ip,如果设置了用户名暗码也填上- <script setup>
- import { ref, onMounted, onUnmounted, watch } from 'vue';
- import { ElMessage, ElButton, ElInput, ElTable, ElTableColumn } from 'element-plus';
- import mqtt from 'mqtt'; // 导入 mqtt,默认导出的是客户端工厂函数
- import { meslist } from '@/api/mes'; // 引入 meslist API
- // 响应式变量
- const SelectTopic = ref(''); // 可以动态修改的选择项(如输入框内容)
- const results = ref([]); // 用来存储搜索结果
- const loading = ref(false); // 用于控制加载状态
- const error = ref(null); // 用于显示错误信息给用户
- let client;
- // 搜索函数
- const search = async () => {
- if (!SelectTopic.value.trim()) {
- ElMessage.warning("请输入有效的搜索内容");
- return;
- }
- loading.value = true; // 开始加载
- error.value = null; // 清除之前的错误信息
- try {
- const response = await meslist(SelectTopic.value);
- console.log('API Response:', response); // 输出原始响应以便调试
- // 如果是数组,则按照新逻辑处理
- if (Array.isArray(response)) {
- if (response.length > 0) {
- results.value = response;
- console.log('搜索成功:', results.value);
- } else {
- ElMessage.info('未找到相关结果');
- results.value = [];
- }
- }
- // 如果都不是,则抛出异常
- else {
- throw new Error('API 返回的数据格式不正确');
- }
- } catch (err) {
- // 更详细的错误信息记录
- console.error('搜索失败:', err);
- ElMessage.error('搜索失败,请稍后重试或检查网络连接');
- results.value = [];
- } finally {
- loading.value = false; // 搜索完成,结束加载状态
- }
- };
- // MQTT 连接配置
- const connectMqtt = () => {
- const brokerUrl = 'ws://ip/mqtt'; // 使用提供的主机名、端口和路径
- const clientId = 'emqx_MTgwND'; // 客户端 ID
- const options = {
- username: 'web', // 替换为实际的用户名~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- password: '123', // 替换为实际的密码~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- keepalive: 60, // Keepalive 时间
- clean: true, // Clean Start
- sessionExpiryInterval: 0, // 会话过期时间
- protocolVersion: 5, // 协议版本 MQTT 5
- };
- client = mqtt.connect(brokerUrl, options);
- client.on('connect', () => {
- console.log('Connected to MQTT broker');
- if (SelectTopic.value.trim()) {
- client.subscribe(SelectTopic.value, (err) => {
- if (err) {
- console.error('Failed to subscribe:', err);
- } else {
- console.log('Subscribed to topic:', SelectTopic.value);
- }
- });
- }
- });
- client.on('message', (topic, message) => {
- console.log('Received message:', topic, message.toString()); // 调试信息
- try {
- const msg = JSON.parse(message.toString());
- // 更新结果列表
- results.value = [...results.value, {
- id: msg.id || 0,
- topic: topic,
- payload: msg.payload || message.toString(),
- qos: msg.qos || 0,
- timestamp: new Date().toLocaleString()
- }];
- } catch (e) {
- console.error('Failed to parse message:', e);
- // 如果解析失败,直接将原始消息作为字符串处理
- results.value = [...results.value, {
- id: -1,
- topic: topic,
- payload: message.toString(),
- qos: 0,
- timestamp: new Date().toLocaleString()
- }];
- }
- });
- client.on('error', (err) => {
- console.error('MQTT connection error:', err);
- });
- client.on('close', () => {
- console.log('MQTT connection closed');
- });
- };
- // 断开 MQTT 连接
- const disconnectMqtt = () => {
- if (client) {
- client.end();
- client = null;
- }
- };
- // 监听 SelectTopic 的变化
- watch(SelectTopic, (newVal) => {
- if (newVal.trim()) {
- disconnectMqtt();
- connectMqtt();
- } else {
- disconnectMqtt();
- }
- });
- // 在组件挂载时启动 MQTT 连接
- onMounted(() => {
- if (SelectTopic.value.trim()) {
- connectMqtt();
- }
- });
- // 在组件卸载时断开 MQTT 连接
- onUnmounted(() => {
- disconnectMqtt();
- });
- </script>
- <template>
- <div class="container">
- <h1 class="title">历史数据查看</h1>
- <div class="input-container">
- <el-input
- v-model="SelectTopic"
- placeholder="请输入搜索内容"
- size="large"
- clearable
- class="input-box"
- />
- </div>
- <div class="button-container">
- <el-button
- type="primary"
- @click="search"
- :loading="loading"
- class="search-button"
- >
- {{ loading ? "加载中..." : "搜索" }}
- </el-button>
- </div>
- <!-- 搜索结果表格 -->
- <el-table v-if="results.length > 0" :data="results" style="width: 100%" border>
- <el-table-column prop="id" label="ID" width="100"></el-table-column>
- <el-table-column prop="qos" label="QoS" width="100"></el-table-column>
- <el-table-column prop="payload" label="Payload"></el-table-column>
- <el-table-column prop="timestamp" label="Timestamp" width="200">
- <template #default="scope">
- {{ scope.row.timestamp }}
- </template>
- </el-table-column>
- </el-table>
- <!-- 如果没有数据或错误时的提示 -->
- <div v-else-if="!loading && SelectTopic.trim()">
- <p class="error-message">{{ error || '没有找到相关结果' }}</p>
- </div>
- <div v-else-if="!loading">
- <p class="placeholder-message">请输入搜索内容</p>
- </div>
- </div>
- </template>
- <style scoped>
- /* 设置容器样式 */
- .container {
- padding: 40px;
- max-width: 1000px;
- margin: 0 auto;
- background-color: #f7f7f7;
- border-radius: 8px;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
- }
- /* 标题样式 */
- .title {
- font-size: 28px;
- font-weight: bold;
- color: #333;
- text-align: center;
- margin-bottom: 30px;
- }
- /* 输入框容器样式 */
- .input-container {
- display: flex;
- justify-content: center;
- margin-bottom: 20px;
- }
- /* 输入框样式 */
- .input-box {
- width: 50%;
- font-size: 16px;
- }
- /* 按钮容器样式 */
- .button-container {
- display: flex;
- justify-content: center;
- margin-bottom: 20px;
- }
- /* 按钮样式 */
- .search-button {
- width: 200px;
- height: 40px;
- font-size: 16px;
- }
- /* 错误消息样式 */
- .error-message {
- color: red;
- text-align: center;
- font-size: 16px;
- }
- /* 占位符消息样式 */
- .placeholder-message {
- text-align: center;
- font-size: 16px;
- color: #888;
- }
- </style>
复制代码 在输入框输入,就可以订阅相应的主题了,然后其他客户端发送此主题的内容,就可以订阅吸收到了。由于我的代码内里尚有给后端发哀求的部分,以是干系后端接口必要你们自己完成大概把这部分的代码删掉。

|