本教程可以实现连接wss,接受数据,你可以在任意页面使用接收到的数据
我封装并不是全面的,只包括接收数据,没有发送数据部分,所以根据自己的需求进行调整~
大概讲下我这里的逻辑:
在你需要的页面进行连接websocket(wss),连接之后服务器会向客户端发送数据,然后我们把数据存在pinia中,这样我们在需要使用数据的页面随取随用,因为使用的数据需要是实时的,虽然在pinia中数据是响应式的,但我们在页面从pinia中获取数据之后会变成非响应式的,所以就需要用到storeToRefs把获取到的数据也声明为响应式,接下来就可以使用watch监听数据的变化,在数据变化之后做处理~
准备工作:确保你的项目是vue3,并且已安装pinia(vue2的项目可以使用vuex)
代码部分
1、pinia文件配置(在根目录下新建store/index.js文件)
import { defineStore } from 'pinia'
export const useMyStore = defineStore('myStore', {
state: () => ({
socketData: null,//websocket推送的数据
}),
actions: {
updateSocketData(data) { //更新数据
this.socketData = data
},
},
persist: true
})
2、新建一个封装websocket的js文件,可以在根目录下新增common/websocketManager.js
我这里只接受服务器端的数据,实现页面数据更新。就没有写向服务器发送数据部分,如果你的需求类似于聊天室,可以自己加上心跳机制和消息发送。\
import {useMyStore} from '@/store/index.js'
const store = useMyStore()
const url ='你的wss地址';
let isCreate = false; // WebSocket 是否创建成功
let isConnect = false; // 是否已经连接
let isInitiative = false; // 是否主动断开
let reconnectTimer = null; // 断线重连定时器
let socketExamples = null; // websocket实例
let againTime = 3; // 重连等待时间(单位秒)
// 初始化websocket连接
function initSocket(){
if (socketExamples) {
socketExamples.close()
socketExamples = null;
}
// 初始化
const userID = uni.getStorageSync('userInfo').id
socketExamples = uni.connectSocket({
url: url+userID,
success: (res) => {
isCreate = true;
},
fail: (rej) => {
console.error(rej);
isCreate = false;
},
});
createSocket();
}
// 创建websocket连接
function createSocket() {
if (isCreate) {//创建成功
// 监听 WebSocket 连接打开事件
try {
socketExamples.onOpen(() => {
console.log("WebSocket 连接成功");
isConnect = true;//连接成功
clearTimeout(reconnectTimer);//清除重连
});
// 监听 WebSocket 接受到服务器的消息事件
socketExamples.onMessage((res) => {
// console.log("收到消息",res);
store.updateSocketData(JSON.parse(event.data))
});
// 监听 WebSocket 连接关闭事件
socketExamples.onClose(() => {
console.log("WebSocket 关闭了");
isConnect = false;
reconnect();
});
// 监听 WebSocket 错误事件
socketExamples.onError((res) => {
console.log("WebSocket 出错了");
reconnect();
});
} catch (error) {
console.warn(error);
}
} else {
console.warn("WebSocket 初始化失败!");
}
}
// 重新连接
function reconnect() {
clearTimeout(reconnectTimer);
// 如果不是人为关闭的话,进行重连
if (!isInitiative) {
reconnectTimer = setTimeout(() => {
initSocket();
}, againTime * 1000);
}
}
// 关闭 WebSocket 连接
function closeSocket() {
socketExamples.close({
success() {
data = null;
isCreate = false;
isConnect = false;
isInitiative = true;
socketExamples = null;
reconnectTimer = null;
clearTimeout(reconnectTimer);
console.log("关闭 WebSocket 成功");
},
fail() {
console.log("关闭 WebSocket 失败");
},
});
}
export const websocetObj ={
initSocket,//连接
closeSocket//关闭
};
3、在需要连接wss的页面连接并使用。
注:建议只连接一次,然后在需要的页面使用即可,如果频繁的连接和关闭也会影响性能。
import { ref,watch} from 'vue'
import { onShow,onUnload} from "@dcloudio/uni-app"
import { storeToRefs } from 'pinia'
import {websocetObj} from "@/common/websocketManager.js";
import {useMyStore} from '@/store/index.js'
const store = new useMyStore();
const { socketData } = storeToRefs(store);
const gameDetail = ref({});
onShow(()=>{
websocetObj.initSocket();
})
//监听wss数据的变化
watch((socketData),(newval)=>{
gameDetail.value = newval;
})
4、在需要关闭的页面关闭wss
import { onUnload} from "@dcloudio/uni-app"
import { storeToRefs } from 'pinia'
import {websocetObj} from "@/common/websocketManager.js";
import {useMyStore} from '@/store/index.js'
onUnload(()=>{
websocetObj.closeSocket();
})