前情提要:由于公司要做长连接实时报警的东西,由于之前写过websocket相关的,我觉得很好写。但是,这次不一样,后端用了订阅,而且所用技术不详,不知道用的什么技术搞得,导致前端对接很困难。
主要表现为
- 链接在测试网站可以和后端保持长链接,但是我这边代码不行。(经测试,代码无问题,测试地址为网上扒的
ws://broker.emqx.io:8083/mqtt
,技术方案为
- 第一种方案失败后,采用后端给我的测试demo方案,具体为
- 经测试,所有方案,失败的表现形式为:无限重连,即建立链接之后请求只有上传数据,无下载数据,所有步骤卡在reconnect上,且报错为undefined。
- (如果你卡在链接第一步,地址报错,请问一下leader是否采用了https请求,该方案会导致ws变成wss请求,从而导致报错。 光找这问题差点圆寂)
然后我懵了,真的懵了,光这些技术方案,搞了我一天,第二天工作汇报都有点不好意思,然后我灵机一动,人家测试网站能用,那我干脆去扒测试网站代码。(狗急跳墙.jpg)
正文:
这次采用的是paho MQTT.javascript,我保证这个能用,如果用不起来,干死后端吧(我一个前端有什么办法.jpg)
请先保证在测试网址上能跑通
第一步:在index.html页面载入js
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
我注释的那条为:将http请求变成https
第二步:写js文件
//mqtt 远程连接 订阅消息
import {mapGetters,mapActions } from 'vuex'
var passWord = "mascj@lm177";
var username = "admin";
var hostname = "10.161.3.5"; //替换成的地址
var port = "61614"; //使用ws/WSS协议的接口地址
var clientId = makeid();
var connected = false;
var client = new Paho.MQTT.Client(hostname, Number(port), "/mqtt", clientId);
logMessage("INFO", "Connecting to Server: [Host: ", hostname, ", Port: ", port, ", Path: ", client.path, ", ID: ", clientId, "]");
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// client.onConnected = onConnected;
var options = {
invocationContext: { host: hostname, port: port, clientId: clientId },
timeout: 5,
keepAliveInterval: 60,
cleanSession: true,
useSSL: false,//当其为true时,开启wss,为false时,开启ws模式
//reconnect: true,
onSuccess: onConnect,
onFailure: onFail,
mqttVersion: 4
};
options.userName = username;
options.password = passWord;
client.connect(options);
//订阅
function subscribe() {
var topic = "hk:warning:broadcast:xqsv";
var qos = 0;
logMessage("INFO", "Subscribing to: [Topic: ", topic, ", QoS: ", qos, "]");
client.subscribe(topic, { qos: Number(qos) });
}
function publish(ledState) {
var topic = "hk:warning:broadcast:xqsv";
var qos = 0;
var message = ledState;
var retain = false;
message = "{\"LED\":\"" + message + "\"} ";
logMessage("INFO", "Publishing Message: [Topic: ", topic, ", Payload: ", message, ", QoS: ", qos, ", Retain: ", retain, "]");
message = new Paho.MQTT.Message(message);
message.destinationName = topic;
message.qos = Number(qos);
message.retained = retain;
client.send(message);
}
function disconnect() {
logMessage("INFO", "Disconnecting from Server.");
client.disconnect();
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
logMessage("INFO", "Connection Lost. [Error Message: ", responseObject.errorMessage, "]");
}
connected = false;
}
// called when a message arrives
function onMessageArrived(message) {
let msg = {destinationName:message.destinationName,payloadString:message.payloadString}
if (!!msg.destinationName&&msg.destinationName=='hk:warning:broadcast:xqsv'){
localStorage.setItem('mqtt', JSON.stringify(msg))
}
logMessage("INFO", "Message Recieved: [Topic: ", message.destinationName, ", Payload: ", message.payloadString, ", QoS: ", message.qos, ", Retained: ", message.retained, ", Duplicate: ", message.duplicate, "]");
}
// called when the client connects
function onConnect(context) {
// Once a connection has been made, make a subscription and send a message.
var connectionString = context.invocationContext.host + ":" + context.invocationContext.port + context.invocationContext.path;
logMessage("INFO", "Connection Success ", "[URI: ", connectionString, ", ID: ", context.invocationContext.clientId, "]");
connected = true;
}
function onConnected(reconnect, uri) {
// Once a connection has been made, make a subscription and send a message.
logMessage("INFO", "Client Has now connected: [Reconnected: ", reconnect, ", URI: ", uri, "]");
connected = true;
}
function onFail(context) {
logMessage("ERROR", "Failed to connect. [Error Message: ", context.errorMessage, "]");
connected = false;
}
function makeid() {
var text = "sub-";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 15; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
function logMessage(type, ...content) {
var date = new Date();
var timeString = date.toUTCString();
var logMessage = timeString + " - " + type + " - " + content.join("");
if (type === "INFO") {
console.info(logMessage);
} else if (type === "ERROR") {
console.error(logMessage);
} else {
console.log(logMessage);
}
}
export {
subscribe
}
具体要改的都在文件被标注了
第三步:vue组件中引入
import {subscribe} from "../../config/tools/utility_paho";
export default {
name:'bigScreenIndexView',
data () {
return {
dateFormat:dateFormat,
date:new Date(),
}
},
components: {
bigScreenLeft,bigScreenMiddle,bigScreenRight
},
mounted() {
//显示当前日期时间
let _this = this// 声明一个变量指向Vue实例this,保证作用域一致
this.timer = setInterval(() => {
_this.date = new Date(); // 修改数据date
}, 1000);
},
created () {
// var parameter={
// "password": "d26ff09d83a333dd",
// "username": "tokenuser"
// };
// this.getToken(parameter);
setTimeout(()=>{
this.connect();
},10000)
},
methods: {
...mapActions(["getToken"]),
backHome(){
let routeData = this.$router.resolve({
path: "/homePage",
});
window.open(routeData.href, "_self");
},
connect(){
localStorage.setItem('mqtt','');//先将本地存储清空
subscribe();//建立订阅
},
}
}
如果需要监听状态,去本地存储里拿mqtt
以上就是所有的解决方案了。
下面为参考链接:
Web前端 使用paho MQTT.javascript来连接百度IOT(天工物接入)
求求惹,给个赞吧!!!!!!!!
2022/1/17 paho.mqtt.javascript 断开问题 故障修复
故障打印:Connection Lost. [Error Message: AMQJS0008I Socket closed.]
故障表现:链接成功之后,没几分钟便会断开(或订阅消息时,接受完消息便会断开)
代码修复:心跳重连时间改为10
代码:
var options = {
invocationContext: { host: hostname, port: port, clientId: clientId },
timeout: 5,
keepAliveInterval: 10,//当时间为60时会出现断链问题
cleanSession: true,
useSSL: true,//当其为true时,开启wss,为false时,开启ws模式
// reconnect: true,
onSuccess: onConnect,
onFailure: onFail,
mqttVersion: 4
};