vue2封装websocket,全局持久监听
前言
在vue前端项目中全局使用websocket,需要用到全局状态管理(这里使用vuex),为方便以后类似场景搭建,这里记录一下。
具体步骤
封装websocket类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55// @/utils/websocket.js
export default class WebSocketClient {
constructor(url, onMessageCallback, onErrorCallback) {
this.token = localStorage.getItem("lidar_token");
let socketUrl = `ws://your-base-url`;
this.url = socketUrl + url;
this.onMessageCallback = onMessageCallback;
this.onErrorCallback = onErrorCallback || (() => {});
this.ws = null;
this.reconnectDelay = 5000; // 重连间隔
}
connect() {
this.ws = new WebSocket(this.url, [this.token]);
this.ws.onopen = () => {
console.log("socket连接成功");
};
this.ws.onmessage = (event) => {
const raw = event.data;
const data = JSON.parse(raw);
if (this.onMessageCallback) {
this.onMessageCallback(data);
// this.onMessageCallback(event.data);
}
};
this.ws.onerror = (error) => {
console.error("连接失败:", error);
this.onErrorCallback(error);
};
this.ws.onclose = () => {
console.log("连接已断开.");
// 可以加一个字段,是否需要重连
// console.log("连接已断开,尝试重连...");
// setTimeout(() => this.connect(), this.reconnectDelay);
};
}
sendMessage(message) {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(message);
} else {
console.error("WebSocket is not open.");
}
}
close() {
if (this.ws) {
this.ws.close();
}
}
}配置状态管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71// @/store/modules/websocket.js 管理状态
import WebSocketClient from "@/utils/websocket";
const state = {
websocket: null,
isConnected: false,
messages: null,
};
const mutations = {
SET_WEBSOCKET(state, websocket) {
state.websocket = websocket;
},
SET_CONNECTION_STATUS(state, status) {
state.isConnected = status;
},
ADD_MESSAGE(state, message) {
state.messages= message;
},
CLEAR_MESSAGES(state) {
state.messages= null;
},
};
const actions = {
initializeWebSocket({ commit, dispatch }, url) {
const websocket = new WebSocketClient(
url,
(message) => {
dispatch("handleMessage", message);
},
(error) => {
console.error("WebSocket error from vuex:", error);
},
true
);
websocket.connect();
commit("SET_WEBSOCKET", websocket);
commit("SET_CONNECTION_STATUS", true);
},
closeWebSocket({ commit, state }) {
if (state.websocket) {
state.websocket.close();
commit("SET_CONNECTION_STATUS", false);
}
},
sendMessage({ state }, message) {
if (state.websocket) {
state.websocket.sendMessage(message);
} else {
console.error("WebSocket is not connected.");
}
},
// TODO:这里可以进行消息分类的处理
handleMessage({ commit }, message) {
commit("ADD_MESSAGE", message);
},
};
const getters = {
isConnected: (state) => state.isConnected,
messages: (state) => state.messages,
};
export default {
namespaced: true,
state,
mutations,
actions,
getters,
};全局派发
1
2
3
4
5
6
7
8
9
10
11
12
13// main.js
new Vue({
router,
store,
render: (h) => h(App),
created() {
const websocketUrl = "/your-url";
this.$store.dispatch("websocket/initializeWebSocket", websocketUrl);
},
beforeDestroy() {
this.$store.dispatch("websocket/closeWebSocket");
},
}).$mount("#app");组件中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 在组件中获取/监听状态
import { mapGetters } from "vuex";
computed: {
...mapGetters("websocket", ["messages", "isConnected"]),
},
watch: {
messages: {
handler(newMessages) {
if (newMessages) {
// your function
}
},
deep: true,
},
},more: 单个页面使用websocket
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 组件使用: 组件内声明一个socketServiceData状态; beforeDestroy钩子记得.close()
if (this.socketServiceData) {
this.socketServiceData.close();
this.socketServiceData = null;
}
this.socketServiceData = new WebSocketClient(
"/your-url",
(message) => {
// your function
},
(error) => {
// your function
}
);
this.socketServiceData.connect();
done!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ra-Liz's Blog!
评论
ValineGitalk