vue3:websocket的封装与使用

6 篇文章 0 订阅
4 篇文章 0 订阅

前言:vue3+pinia项目

1.引入ws

yarn add ws

2.新建websocket.js类

let webSock = null;
let global_callback = null;
let isConnect = false; //连接标识 避免重复连接
let rec; //断线重连后,延迟5秒重新创建WebSocket连接  rec用来存储延迟请求的代码
let socketParams = {
  pageKey: -1
};
let isActiveClose = false; // 是否主动关闭socket


let serverPort = "8080"; // webSocket连接端口
let wsUri = "ws://" + "xxx.xx.xx.xx" + ":" + serverPort;
// let serverPort = "8081"; // webSocket连接端口
// let wsUri = "ws://" + "192.168.50.156" + ":" + serverPort;

function createWebSocket(callback) {
  if (webSock == null || Object.prototype.toString.call(webSock) !== "[object WebSocket]") {
    initWebSocket(callback);
  }
}

function initWebSocket(callback) {
  log("init webSocket");
  global_callback = callback;
  // 初始化websocket
  webSock = new WebSocket(`${wsUri}?Authorization=${填写登录令牌token}`);
  webSock.onmessage = function(e) {
    websocketOnMessage(e);
  };
  webSock.onclose = function(e) {
    websocketClose(e);
  };
  webSock.onopen = function() {
    websocketOpen();
  };

  // 连接发生错误的回调方法
  webSock.onerror = function() {
    websocketError();
  };
}


//心跳设置
const heartCheck = {
  timeout: 20000, //每段时间发送一次心跳包 这里设置为20s
  timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)

  start: function() {
    this.timeoutObj = setInterval(function() {
      if (isConnect) webSock.send(JSON.stringify(socketParams));
    }, this.timeout);
  },

  reset: function() {
    clearTimeout(this.timeoutObj);
    this.start();
  }
};

//定义重连函数
let reConnect = () => {
  log("尝试重新连接");
  if (isConnect) return; //如果已经连上就不在重连了
  rec && clearTimeout(rec);
  rec = setTimeout(function() { // 延迟5秒重连  避免过多次过频繁请求重连
    if (!isConnect) {
      initWebSocket();
    }
  }, 5000);
};

// 实际调用的方法
function sendSock(agentData) {
  if (webSock.readyState === webSock.OPEN) {
    // 若是ws开启状态
    websocketSend(agentData);
  } else if (webSock.readyState === webSock.CONNECTING) {
    // 若是 正在开启状态,则等待1s后重新调用
    setTimeout(function() {
      sendSock(agentData);
    }, 1000);
  } else {
    // 若未开启 ,则等待1s后重新调用
    setTimeout(function() {
      sendSock(agentData);
    }, 1000);
  }
}

function closeSock({ activeClose = false }) {
  log(`关闭了 activeClose = ${activeClose}`);
  isActiveClose = activeClose;
  // 清除心跳定时器
  heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
  // 清除重连定时器
  rec && clearTimeout(rec);
  if (isActiveClose) {
    // 关闭socket
    webSock.close();
  }
  // 初始化相关变量
  webSock = null;
  isConnect = false;
}

// 数据接收
function websocketOnMessage(msg) {
  // global_callback(JSON.parse(msg.data));
  if (!msg || !msg.data) {
    // 可能得情况 - 心跳机制、无关信息接收
    log("收到数据:空消息");
    return;
  }
  log("收到数据:"+ msg.data);
  // 收到信息为Blob类型时
  let result = null;
  if (msg.data instanceof Blob) {
    const reader = new FileReader();
    reader.readAsText(msg.data, "UTF-8");
    reader.onload = (e) => {
      result = JSON.parse(reader.result);
      //console.log("websocket收到", result);
      global_callback(result);
    };
  } else {
    result = JSON.parse(msg.data);
    //console.log("websocket收到", result);
    global_callback(result);
  }
}

// 数据发送
function websocketSend(agentData) {
  log("发送数据:" + agentData);
  webSock.send(agentData);
}

// 关闭
function websocketClose(e) {
  log("connection closed (" + e.code + ")");
  if (isActiveClose) {
    isActiveClose = false;
    return;
  }
  closeSock({ activeClose: false });
  // 执行重连
  reConnect();
}

const websocketError = () => {
  log("WebSocket连接发生错误");
  closeSock({ activeClose: true });
  // 执行重连
  reConnect();
}

function websocketOpen(e) {
  log("连接打开");
  isConnect = true;
  heartCheck.start(); //发送心跳 看个人项目需求
}

export { sendSock, createWebSocket, closeSock };

3.新建一个pinia Store类

export const websocketStore = defineStore('websocket', () => {
	/**
	 * socket推送过来的全量数据,暴露出去用户对数据变更的监听
	 */
	const serviceMsg = ref({});
	

	/**
	 * 连接webSocket init
	 */
	const init = () => {
		createWebSocket(global_callback);
	};

	/**
	 * websocket的回调函数
	 * @param jsonMsg 表示收到的消息
	 */
	const global_callback = (jsonMsg) => {
		serviceMsg.value = jsonMsg;
		... ...
	};

	/**
	 * webSocket发送消息
	 * @param sendData 发送的json数据
	 */
	const send = (sendData) => {
		sendSock(JSON.stringify(sendData));
	};

	/**
	 * 关闭webSocket
	 */
	const close = ({ isActiveClose = false }) => {
		closeSock({ activeClose: isActiveClose });
	};

	/**
	 * 关闭后重启socket
	 */
	const closeAndRestart = () => {
		close({ isActiveClose: true });
		init();
	};

    ... ...


	return {
		init,
		close,
		closeAndRestart,
		serviceMsg,
        ... ...
	};
});

4.页面中使用

// 在页面挂载完成时启动websocket
onMounted(() => {
  websocketStore().init();
});

// 使用watch函数监听消息变更
watch(
		() => websocketStore().chatMsg,
		(nValue, oValue) => {
			// todo 界面信息更新
		}
);

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3中,我们可以通过封装Websocket类来实现对Websocket使用。通过引用和可以得知,在Vue3中使用Websocket可以实现实时数据传输。为了方便使用,我们可以封装一个好用的Websocket类。具体步骤如下: 1. 首先,安装Websocket的依赖,可以通过npm或yarn等包管理工具进行安装。 2. 创建一个Websocket类,该类应该包含Websocket的连接、发送消息和接收消息的方法。可以参考引用中提到的封装Websocket类的方法。 3. 在Vue3中,可以将Websocket封装成一个Vue插件,以便全局使用。具体步骤如下: - 创建一个插件文件,例如`websocket-plugin.js`。 - 在插件文件中,引入Websocket类并创建一个Vue插件对象。 - 在插件对象的`install`方法中,将Websocket实例挂载到Vue的原型上,以便在组件中可以通过`this.$websocket`来访问Websocket实例。 - 最后,导出该插件对象。 - 示例代码如下: ```javascript import Websocket from './websocket.js'; const WebsocketPlugin = { install(Vue) { Vue.prototype.$websocket = new Websocket('ws://localhost:8080'); }, }; export default WebsocketPlugin; ``` 4. 在Vue项目中,将该插件引入并使用。可以在`main.js`或其他入口文件中使用`app.use()`方法来安装该插件。示例代码如下: ```javascript import { createApp } from 'vue'; import App from './App.vue'; import WebsocketPlugin from './websocket-plugin.js'; const app = createApp(App); app.use(WebsocketPlugin); app.mount('#app'); ``` 通过以上步骤,我们就可以在Vue3中封装Websocket,并在全局范围内使用了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [基于Vue3封装一个好用的Websocket](https://blog.csdn.net/qq_27244301/article/details/130098672)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值