一、实现思路
1.前端单独写一个转图片的组件imageUpload.vue,并设置路由/imageUpload,当访问地址http://10.18.0.200:8081/imageUpload 时,调用imageUpload.vue组件。当前项目的运行地址http://10.18.0.200:8081
2.后端向前端推送消息topic,同时后端(服务器端)启动浏览器进程打开一个新页面,模拟地址栏地址中输入http://10.18.0.200:8081/imageUpload请求----即调用了imageUpload.vue组件(初始化,进行了websocket连接)。因为是后端启动的浏览器进程,所以在前端(浏览器端)看来并没有打开新页面,用户感知不到。但是测试的时候你可以通过自己 访问http://10.18.0.200:8081/imageUpload 来进行测试
3.imageUpload.vue中的逻辑
1)定义一个websocket,订阅后端推送的消息topic(消息里有转图片需要的原始数据),一旦接收到后端返回的数据,就放在一个数组todoList中
2)当监听到todoList的变化时,将数据转换成转图片需要的数据,转成图片,将图片(formData的格式)回传给后端。
3)每次处理完一条数据就从todoList删除第一条数据,当有数据时每次都取第一条数据进行2)中的处理
二、代码
注:此处只提供前端向后端传图片思路的大致框架,不能正常运行。转图片的代码未提供,还需整理。
<template>
<div>
<!--转图片组件 省略传参之类的,此处只提供思路-->
<MakeImage class="makeImage"></MakeImage>
</div>
</template>
<script>
// 转图片组件
import MakeImage from "./riskAssessment/MakeImage";
// 回传图片接口、获取mqtt连接地址、用户名和密码的接口
import { _uploadAssessmentImage, _getEMQ } from "@/api/riskAssessmentAPI.js";
import mqtt from "mqtt";
export default {
data() {
return {
// 定义websocket
websocket: null,
// 需要回传的队列
todoList: [],
};
},
async mounted() {
console.log("imageUpload mounted");
// 获取连接信息
let connectMessage = await this.getEMQ();
console.log("connetMessage", connectMessage);
let wsUrl = connectMessage.url;
let options = {
username: connectMessage.username,
password: connectMessage.password,
};
console.log("connect url:", wsUrl, options);
this.websocket = mqtt.connect(wsUrl, options);
// 重连
this.websocket.on("reconnect", (error) => {
console.log("正在重连:", error);
});
// 建立连接,订阅主题
this.websocket.on("connect", () => {
// 订阅 回传评估结果的主题
this.websocket.subscribe("vte/asset/report", (error) => {
if (error) {
console.log("error:", err);
} else {
console.log("回传评估结果 sub success");
}
});
});
// 连接失败
this.websocket.on("error", (error) => {
console.log("连接失败:", error);
});
// 接收到服务器消息时
this.websocket.on("message", (topic, message) => {
console.log("websocket message", JSON.parse(message.toString()), topic);
// 获取评估结果
let assessmentReport = JSON.parse(message.toString());
this.todoList.push(assessmentReport);
});
// 关闭连接时
this.websocket.on("close", () => {
console.log("close");
});
},
methods: {
//获取mqtt连接地址、用户名和密码
getEMQ({ commit }) {
return new Promise((resolve, reject) => {
_getEMQ().then((res) => {
const { data } = res;
commit("SETMQCONFIG", JSON.parse(data));
resolve(JSON.parse(data));
});
});
},
// 获取转图片所需数据
async getImageData(todoData) {
// 数据处理,处理为转图片需要的数据
},
// 回传图片
uploadAssessmentImage(imageobject) {
console.log("imageobject", imageobject);
let params = {
bucket: "test",
};
_uploadAssessmentImage(imageobject.formdata, params)
.then((result) => {
this.todoList.shift();
})
.catch((error) => {
console.log("error", error);
this.todoList.shift();
});
},
//生成图片
async createImages(todoData) {
// 获取转图片所需数据
await this.getImageData(todoData);
// 转图片
let imageDoms = document.getElementsByClassName("makeImage");
// 兼容有多条数据同时需要转图片的情况
Object.keys(imageDoms).map(async (item, index) => {
console.log("imageDoms", item, index, imageDoms[index]);
// 调用转图片方法生成图片
await imageDoms[index]["__vue__"].handlePrint(index);
});
},
},
watch: {
todoList: {
async handler(newval) {
console.log("todoList", newval, newval.length);
//队列里有数据再回传
if (newval.length > 0) {
console.log("回传评估结果图片");
//获取转图像需要的数据
await this.createImages([newval[0]]);
}
},
},
},
};
</script>
三、注意事项
1.如果进入 http://10.18.0.200:8081/imageUpload 页面有权限,需要重新登录等,需要手动在imageUpload的mounted函数中进行处理。比如直接进入这个页面会有重新登录的提示,那么你应该在imageUpload中手动调用登录函数登录,以便imageUpload组件能够被正常加载。
/*
感谢chl的指导!
希望对你有帮助!
如有错误,欢迎指正!非常感谢!
*/