封装websocket

server/2024/10/17 4:00:04/

摘要

本文将介绍两种不同的WebSocket客户端封装方法:使用函数封装和使用类封装。我们将分析它们的实现方式、特点和适用场景,以及如何根据项目需求选择合适的封装方式。

1. 引言

WebSocket提供了全双工通信渠道,允许服务器主动发送信息给客户端。在实际开发中,封装WebSocket客户端可以简化开发流程,提高代码的可维护性和可复用性。

2. 函数封装:createWebSocket

createWebSocket函数是一种简单的封装方式,它通过接收必要的参数来创建和管理WebSocket连接。以下是其主要特点:

  • 简洁性:作为一个函数,它提供了一种快速且直接的方式来处理WebSocket连接。
  • 自动重连:实现了自动重连机制,能够在连接断开时尝试重新连接。
  • 心跳检测:通过定时发送心跳包来保持连接的活跃状态。
  • 灵活性:提供了发送消息和关闭连接的方法,使得调用者可以灵活地控制WebSocket的生命周期。

3. 类封装:WebSocketClient

WebSocketClient类提供了面向对象的方式来管理WebSocket连接,具有以下特性:

  • 封装性:将WebSocket的创建、管理和销毁封装在一个类中,提高了代码的模块化。
  • 状态管理:通过属性来管理WebSocket的状态,如是否在重连中、是否手动关闭等。
  • 错误处理:拥有错误消息队列,能够在连接失败时缓存消息,并在重连成功后发送。
  • 事件监听:定义了多种事件处理方法,如onopenonerroroncloseonmessage,使得状态变化更加可控。

export function createWebSocket(url, onOpen, onMessage) {if (!url) return;let canReconnect = true;// 避免重复连接let lockReconnect = false;let needReconnect = true;let ws = null;connect();heartCheck();// 连接服务端function connect() {ws = new WebSocket(url);ws.onopen = function () {if (onOpen) {onOpen();}};ws.onmessage = function (msg) {if (msg && msg.data) {let response = JSON.parse(msg.data);//console.log(response);if (onMessage) {onMessage(response);} else {canReconnect = false;}}};ws.onerror = function () {console.log("链接错误");reconnect();};ws.onclose = function () {console.log("close");if (!needReconnect) {ws.close();} else {reconnect();}};}// 重新连接服务端function reconnect() {if (!canReconnect || lockReconnect) {return;}console.log("reconnect", "reconnect");lockReconnect = true;setTimeout(function () {connect();lockReconnect = false;}, 5000);}// 保持心跳连接function heartCheck() {if (ws && ws.readyState === 1) {ws.send(JSON.stringify({id: new Date().getTime(),method: "PING",}));}setTimeout(function () {heartCheck();}, 15000);}// 发送websocket消息function sendMessage(message) {if (ws && ws.readyState === 1) {ws.send(message);} else {console.log("WebSocket is not open");}}// 关闭websocket连接function closeWs() {needReconnect = false;ws.close();}return {ws,sendMessage,closeWs,};
}

class WebSocketClient {// 要连接的URLurl// 一个协议字符串或一个协议字符串数组。// 这些字符串用来指定子协议,这样一个服务器就可以实现多个WebSocket子协议protocols// WebSocket 实例ws// 是否在重连中isReconnectionLoading = false// 延时重连的 idtimeId = null// 是否是用户手动关闭连接isCustomClose = false// 错误消息队列errorStack = []constructor(url, protocols) {this.url = url;this.protocols = protocols;this.ws = null;this.onOpen = null;this.onMessage = null;this.connect();}connect() {if ("WebSocket" in window) {// 实例化this.ws = new WebSocket(this.url, this.protocols);// 监听事件this.onopen();this.onerror();this.onclose();} else {console.log("你的浏览器不支持 WebSocket");}}// 监听成功onopen() {this.ws.onopen = () => {console.log(this.ws, "onopen");// 发送成功连接之前所发送失败的消息this.errorStack.forEach((message) => {this.send(message);});this.errorStack = [];this.isReconnectionLoading = false;};}// 监听错误onerror() {this.ws.onerror = (err) => {console.log(err, "onerror");this.reconnection();this.isReconnectionLoading = false;};}// 监听关闭onclose() {this.ws.onclose = () => {console.log("onclose");// 用户手动关闭的不重连if (this.isCustomClose) return;this.reconnection();this.isReconnectionLoading = false;};}// 接收 WebSocket 消息async onmessage(fn) {this.ws.onmessage = (event) => {try {const data = JSON.parse(event.data)fn(data )} catch (error) {console.log(error, 'error')}}}// 重连reconnection() {// 防止重复if (this.isReconnectionLoading) returnthis.isReconnectionLoading = trueclearTimeout(this.timeId)this.timeId = setTimeout(() => {this.createWs()}, 3000)}// 发送消息send(message) {// 连接失败时的处理if (this.ws.readyState !== 1) {
//没有发送成功的信息保存下来,链接成功后重新发送this.errorStack.push(message)return}this.ws.send(message)}// 手动关闭close() {this.isCustomClose = truethis.ws.close()}// 手动开启start() {this.isCustomClose = falsethis.reconnection()}// 销毁destroy() {this.close()this.ws = nullthis.errorStack = nullthis.eventCenter = null}}


http://www.ppmy.cn/server/103974.html

相关文章

基于微信小程序的外卖订餐系统设计与实现

外卖| 订餐小程序| 外卖订餐小程序 博主介绍:✌️大家好!我是Coder-coco,一名专注以理论为基础、实战为主的技术博主,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收…

高性能Web服务器-- Nginx 的架构与安装详解

1.1 Nginx 概述 1.1.1 Nginx简介 Nginx:engine X ,2002年开发,分为社区版和商业版(nginx plus ) 2019年3月11日 F5 Networks 6.7亿美元的价格收购 Nginx是免费的、开源的、高性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理…

CSS的:last-of-type伪类:精准定位末尾元素的样式秘诀

在CSS中,伪类是一种强大的工具,它允许我们根据文档的上下文关系选择元素,而不仅仅是它们的类型或类名。:last-of-type伪类是这些工具中的一个,它可以用来选择一个父元素中最后一种特定类型的子元素。这种能力在设计复杂的布局时非…

GPT助手的训练流程四个主要阶段( GPT Assistant training pipeline )

GPT助手的训练流程四个主要阶段( GPT Assistant training pipeline ) flyfish 四个阶段 预训练(pre-training) 监督微调(supervised fine tuning, SFT) 奖励建模(reward modeling&#xff09…

java编程 斐波拉契数列算法集锦【斐波拉契数列】【下】【集合类】【Stream函数式编程】

斐波那契数列(Fibonacci sequence),又称黄金分割数列,是一个非常经典的递归问题。斐波那契数列的算法描述: 斐波那契数列,一个令人着迷而又充满神秘色彩的数字序列,它以0和1作为起始&#xff…

【Leetcode 1512 】 好数对的数目—— 数组模拟哈希表 与 等差数列求和

给你一个整数数组 nums 。 如果一组数字 (i,j) 满足 nums[i] nums[j] 且 i < j &#xff0c;就可以认为这是一组 好数对 。 返回好数对的数目。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,1,1,3] 输出&#xff1a;4 解释&#xff1a;有 4 组好数对&#xff0c;…

【C++贪心】2498. 青蛙过河 II

本文涉及知识点 贪心 优化后不需要二分 LeetCode2498. 青蛙过河 II 给你一个下标从 0 开始的整数数组 stones &#xff0c;数组中的元素 严格递增 &#xff0c;表示一条河中石头的位置。青蛙一开始在第一块石头上&#xff0c;它想到达最后一块石头&#xff0c;然后回到第一块…

我的新项目又来咯!

大家好&#xff0c;我是鱼皮&#xff0c;今天分享个我的新项目公开课预告~ 今晚&#xff08;8 月 22 号&#xff09;晚 20 点 &#xff0c;我会继续在 B 站和抖音《程序员鱼皮》账号 直播新项目&#xff0c;依然是从 0 到 1 全程直播开发&#xff01; 这次的项目周期计划 1 个…