vue使用websocket實現實時數據推送功能
需求:使用websocket不借助插件實現發(fā)布,訂閱,網絡斷開重連,單點登錄后擠號的功能
1.單點登錄(同一賬號同一時間只有一個在線,禁止多用戶登錄)
實現:在用戶登錄之后獲取到token令牌并且存入到本地,可以判斷token令牌是否失效來讓用戶退出登錄,websocket的操作是讓用戶登錄后連接到websocket并且發(fā)送指令,這邊發(fā)送的指令是后端給的,之后前端進行接受消息,如果消息是退出登錄的直接讓他清空本地并且跳轉到登錄頁就行
1.登錄獲取token令牌并且存儲到localStorage
2.在layout也就是頁面主體框架拿到token并且去連接websocket
3.連接成功后直接發(fā)送指令,之后再去監(jiān)聽返給前端的消息之后實現退出操作
url = `${protocol}://websocket的地址,要后端給?token=${token}`;,這個我舉個例子,連接地址應該是這樣的:ws://127.0.0.1:8080?token=362466325,
ws.send(`msg:${this.data.id}`);這個也是后端定的要把賬戶的id給他,這樣去監(jiān)聽登錄
重連,之后消息返回loginOut后做退出登錄的操作,如果鏈接因為各種原因關閉了,直接去請求重連。
retryCount: 0,
maxRetryCount: 5,
retryInterval: 2000, // 重試間隔時間,單位:毫秒
注意??!websocket不能設置請求頭攜帶token好像,試了很多次都不行,用ws插件也不行,只能拼接token給后端了
let ws;
let url = "";
export default {
mounted() {
this.connectWebsocket();
},
methods: {
connectWebsocket() {
let protocol = "ws";
if (typeof WebSocket === "undefined") {
console.log("您的瀏覽器不支持WebSocket");
return;
} else {
if (window.location.protocol == "https:") {
protocol = "wss";
}
let token = localStorage.getItem("token");
url = `${protocol}://websocket的地址,要后端給?token=${token}`;
// 打開一個ws
ws = new WebSocket(url);
ws.onopen = () => {
// 發(fā)送數據
console.log("ws已連接?。?);
ws.send(`msg:${this.data.id}`);
// this.$message.success("ws已連接?。?);
};
// 發(fā)生錯誤時
ws.onerror = (evt) => {
console.log("ws錯誤:", evt);
};
// 關閉連接
ws.onclose = (event) => {
console.warn("WebSocket 已關閉");
console.log("關閉代碼:", event.code);
console.log("關閉原因:", event.reason);
// 處理連接斷開事件
this.handleWebSocketClose();
};
ws.onmessage = (evt) => {
if (evt.data == "loginOut") {
// 此時要做清空數據的操作
this.$message.warning("您的帳號在另一地點登錄,您已被迫下線!!");
this.$router.replace("/");
localStorage.clear();
ws.close();
ws.onclose = () => {
console.log("ws斷開連接成功");
};
}
console.log(evt, "接收到的消息");
};
this.$bus.$emit("Websocket", ws);
}
},
handleWebSocketClose() {
if (this.retryCount < this.maxRetryCount) {
console.log(`正在嘗試第 ${this.retryCount + 1} 次重連...`);
setTimeout(() => {
this.connectWebsocket();
this.retryCount++;
}, this.retryInterval);
} else {
console.error("WebSocket 連接失敗,已達到最大重試次數");
}
},
}
}2.發(fā)布訂閱
注意!!這邊每次發(fā)布的時候都應該重新連一個新的消息,不然和之前的登錄的消息搞混了就不好了,特別是在做操作的時候,比如el-table的編輯操作這些,每次關閉彈窗肯定要關閉websocket,如果和登錄的消息搞混了,關閉彈窗就不能實時接收到單點登錄傳來的消息了
這個connectWebsocket和上面的不是一個,這個是需要實時推送頁面的websocket連接,不會影響全局的單點登錄的。
let websocket;
let url = "";
export default {
connectWebsocket(data) {
let protocol = "ws";
if (typeof WebSocket === "undefined") {
console.log("您的瀏覽器不支持WebSocket");
return;
} else {
if (window.location.protocol == "https:") {
protocol = "wss";
}
let token = localStorage.getItem("token");
url = `${protocol}://后端的給的地址?token=${token}`;
// 打開一個websocket
websocket = new WebSocket(url);
websocket.onopen = () => {
// 發(fā)送數據
// console.log("websocket已連接!!");
websocket.send(data);
this.$message.success("websocket已連接??!");
};
// 發(fā)生錯誤時
websocket.onerror = (evt) => {
console.log("websocket錯誤:", evt);
};
// 關閉連接
websocket.onclose = (event) => {
console.warn("WebSocket 已關閉");
console.log("關閉代碼:", event.code);
console.log("關閉原因:", event.reason);
// 處理連接斷開事件
this.handleWebSocketClose(data);
};
}
},
handleWebSocketClose(data) {
if (this.retryCount < this.maxRetryCount) {
console.log(`正在嘗試第 ${this.retryCount + 1} 次重連...`);
setTimeout(() => {
this.connectWebsocket(data);
this.retryCount++;
}, this.retryInterval);
} else {
this.$message.error("WebSocket 連接失敗!!");
console.error("WebSocket 連接失敗,已達到最大重試次數");
}
},
}2.1模擬編輯操作需要發(fā)布消息
1.點擊編輯后打開并且實時接收
updData(row) {
this.connectWebsocket(`data_imei:${row.id}`);
websocket.onmessage = (evt) => {
//如果收到的消息是msgUpd
if(evt.data=='msgUpd'){
let data = JSON.parse(evt.data);
//把得到的數據進行json轉換之后再給tableData進行展示就行
let tableData.unshift(data)
//也不能一直接受吧,那數據得多少啊,定義一下接收到多少條后截取
if (tableData.length > 500) {
tableData.splice(500);
}
}
}
}
2.關閉彈窗后需要斷開連接
closeWebSocket() {
if (websocket != null) {
websocket.close();
websocket.onclose = () => {
console.log("websocket斷開連接成功");
};
}
},
3.在離開websocket推送頁面后也關閉連接
destroyed() {
if (websocket != null) {
websocket.close();
websocket.onclose = () => {
console.log("websocket斷開連接成功");
};
}
},
到此這篇關于vue使用websocket實現實時數據推送功能的文章就介紹到這了,更多相關vue websocket實時數據推送內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于element-ui對話框el-dialog初始化的校驗問題解決
這篇文章主要介紹了基于element-ui對話框el-dialog初始化的校驗問題解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
從零搭建一個vite+vue3+ts規(guī)范基礎項目(搭建過程問題小結)
這篇文章主要介紹了從零搭建一個vite+vue3+ts規(guī)范基礎項目,本項目已vite開始,所以按照vite官方的命令開始,對vite+vue3+ts項目搭建過程感興趣的朋友一起看看吧2022-05-05

