場景描述
需要做一個功能:相同賬號只允許登錄一次,第二次再次登錄提示“用戶已登錄!”。當前存在一個客戶端、一個Web端共用一個后台。后台的處理邏輯是:監控websocket的狀態,在onClose()
方法中修改用戶的登錄狀態。當前的web端並沒有使用websocket,那么就沒有辦法退出或關閉瀏覽器重置用戶狀態。
實踐
參考文章1:websocket基本用法
參考文章2:全局使用websocket(跨頁面)
創建webSocketApi.js
// websocket 文件
export default {
ws: {},
setWs: function (newWs) {
this.ws = newWs
}
}
將websocket設置為全局變量
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'
import './assets/fonts/iconfont.css'
import websocket from './api/webSocketApi.js'
Vue.config.productionTip = false//關閉生產模式下給出的提示
// 將websocket設置為全局
Vue.prototype.websocket = websocket
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
登錄頁面創建websocket連接
注意:當前頁面的that.ws賦值給了that.websocket.setWs(that.ws)
,所以當前頁面中that.ws等價於that.websocket.ws
//init函數可在頁面加載的時候就進行初始化或者根據自己的業務需求在需要打開通訊的時候在進行初始化
init() {
let that = this;
// 實例化socket,這里的實例化直接賦值給this.ws是為了后面可以在其它的函數中也能調用websocket方法,例如:this.ws.close(); 完成通信后關閉WebSocket連接
if (process.env.NODE_ENV === "development") {
//alert("開發環境");
//this.ws = new WebSocket("ws://localhost:8080/ws/"+this.loginForm.userName)
that.ws = new WebSocket("ws://localhost:8080/ws/"+this.loginForm.userName);
}else {
//alert("生產環境");
//this.ws = new WebSocket("ws://localhost:8080/LPSAServer/ws/"+this.loginForm.userName)
that.ws = new WebSocket("ws://localhost:8080/LPSAServer/ws/"+this.loginForm.userName);
}
that.websocket.setWs(that.ws)
//監聽是否連接成功
that.ws.onopen = ()=> {
console.log('ws連接狀態:' +this.ws.readyState);
//連接成功則發送一個數據
that.ws.send('連接成功');
}
//接聽服務器發回的信息並處理展示
that.ws.onmessage = (data)=> {
console.log('接收到來自服務器的消息:');
console.log(data)
}
//監聽連接關閉事件
that.ws.onclose = ()=>{
//監聽整個過程中websocket的狀態
console.log('ws連接狀態:' + this.ws.readyState);
}
// 主動關閉websocket連接
//關閉
/* this.ws.onclose = function() {
this.ws.close();
};*/
//監聽並處理error事件
that.ws.onerror = function(error) {
console.log(error);
}
}
其它頁面調用
比如:退出按鈕,調用websocket的關閉方法
// 退出登錄
logout() {
this.delToken();
this.$message.success('退出成功')
this.$router.push("/login");
//console.log(that.websocket.ws);
// 關閉websocket連接
let that = this;
that.websocket.ws.close()
},
發現問題:刷新會導致websocket連接關閉
解決方案:設置websocket斷線重連機制
當主頁面刷新的時候,重新建立websocket連接。
相關知識點:
頁面加載時只執行onload
頁面關閉時先執行onbeforeunload,最后onunload
頁面刷新時先執行onbeforeunload,然后onunload,最后onload
HTML DOM addEventListener() 方法
websocketApi修改(適配全局)
// websocket 文件
export default {
ws: {},
setWs: function (userName) {
//this.ws = newWs
if (process.env.NODE_ENV === "development") {
//alert("開發環境");
//this.ws = new WebSocket("ws://localhost:8080/ws/"+this.loginForm.userName)
this.ws = new WebSocket("ws://localhost:8080/ws/"+userName);
}else {
//alert("生產環境");
//this.ws = new WebSocket("ws://localhost:8080/LPSAServer/ws/"+this.loginForm.userName)
this.ws = new WebSocket("ws://localhost:8080/LPSAServer/ws/"+userName);
}
}
}
metheds中設置頁面加載成功后的方法
onloadFn(e) {
//console.log('頁面加載事件')
// 頁面刷新重連websocket
let that = this
//console.log(localStorage.getItem("name"))
//console.log("頁面被刷新了")
that.websocket.setWs(localStorage.getItem("name"))
//console.log(that.websocket.ws)
console.log("websocket重連設置用戶狀態")
updateUser(localStorage.getItem("name"))
},
在create中注冊事件
window.addEventListener('load', e => this.onloadFn(e))