uniapp中websocket的封装及使用,小白闭眼拿

3,118 阅读3分钟

本教程可以实现连接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
})
image.png

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();
})