最近在项目中使用到websocket,于是突发奇想,为什么不能使用websocket代替http请求呢,还想不改变使用方式,于是探索了一番。
想要实现的样子:
- 不想太复杂,在使用的时候还能像正常接口那样,
api.get().then().catch()
- 前端发送请求,以消息的形式传递,
{“action”: “get_user”, "params":{"id": 1}}
通过action来区分不同的请求,这里就不用区分get, post了 - 后端通过action来区分不同的请求,作为同处理
- 像进度条这类的后台直接推数据,前端接收到数据保存到pinia或vuex中, 在相应位置绑定
先来一个简单版本的
utils目录下的websocketService.js
class WebSocketService {
constructor() {
this.socket = new window.WebSocket("ws://127.0.0.1:8000/ws/111");
this.promises = {}; // 保存每个请求过来的{ resolve, reject }
this.socket.onopen = this.handleOpen;
this.socket.onmessage = (message) => this.handleMessage(this, message);
this.socket.onclose = this.handleClose;
}
handleOpen() { console.log("链接成功"); }
handleClose() { console.log("链接关闭"); }
// 发送消息
sendMessage(action, params) {
this.socket.send(JSON.stringify({ action, params }));
}
// 处理消息
handleMessage(that, message) {
const { action, data } = JSON.parse(message.data);
if (that.promises[action]) {
that.promises[action].resolve(data);
delete that.promises[action];
}
}
request(action, params) {
return new Promise((resolve, reject) => {
this.promises[action] = { resolve, reject };
console.log(this.promises)
this.sendMessage(action, params);
});
}
}
const socket = new WebSocketService();
export default socket;
使用方式
import socket from "@/utils/websocketService";
const datas = ref(null);
const get_user = () => {
socket
.request("get_user", { order_by: "id" })
.then((data) => {
console.log("Received data for action get_order:", data);
// 处理获取订单的逻辑
datas.value = data.data;
})
.catch((error) => {
console.error("Error while getting order:", error);
});
};
测试了一下,很完美,尽管理还有很东西要处理。
查看原文: 智灵谷