将websocket封装成一个class,断线可重连

简介: 将websocket封装成一个class,断线可重连

将WebSocket封装成一个可重连的Class

在现代的Web应用中,WebSocket已经成为了一种常见的协议,用于在客户端和服务器之间建立持久性的双向通信。然而,WebSocket连接可能会因为各种原因(如网络不稳定、服务器重启等)而断开。为了提高应用的稳定性和用户体验,我们需要一种机制来在连接断开时自动重连。本文将介绍如何将WebSocket封装成一个可重连的Class,以便在项目中方便地使用。

WebSocket基础

首先,让我们简要回顾一下WebSocket的基础。WebSocket是一种在单个TCP连接上进行全双工通信的协议。它允许服务器主动向客户端发送消息,这与传统的HTTP请求-响应模式不同。WebSocket连接在建立时会进行一次握手,然后保持连接直到客户端或服务器决定关闭它。

在JavaScript中,我们可以使用原生的WebSocket API来创建和管理WebSocket连接。这个API提供了一些事件和方法,如onopenonmessageoncloseonerrorsend,用于处理连接的生命周期和发送/接收消息。

封装WebSocket Class

为了将WebSocket封装成一个可重连的Class,我们需要考虑以下几个方面:

  1. 连接管理:我们需要跟踪WebSocket连接的状态,并在必要时尝试重新连接。
  2. 事件处理:我们需要提供一种机制来让使用者注册和处理WebSocket事件(如打开、关闭、错误和消息)。
  3. 重连策略:我们需要定义一种策略来决定何时以及如何进行重连。

下面是一个简单的示例,展示了如何封装WebSocket Class:

class ReconnectingWebSocket {
  constructor(url, reconnectInterval = 1000) {
    this.url = url;
    this.reconnectInterval = reconnectInterval;
    this.ws = null;
    this.eventHandlers = {
      open: [],
      message: [],
      close: [],
      error: [],
    };

    this.initConnection();
  }

  initConnection() {
    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      this.handleEvent('open');
    };

    this.ws.onmessage = (event) => {
      this.handleEvent('message', event);
    };

    this.ws.onclose = () => {
      this.handleEvent('close');
      this.reconnect();
    };

    this.ws.onerror = (error) => {
      this.handleEvent('error', error);
    };
  }

  handleEvent(eventType, event) {
    const handlers = this.eventHandlers[eventType];
    handlers.forEach((handler) => handler(event));
  }

  on(eventType, handler) {
    this.eventHandlers[eventType].push(handler);
  }

  off(eventType, handler) {
    const handlers = this.eventHandlers[eventType];
    const index = handlers.indexOf(handler);
    if (index !== -1) {
      handlers.splice(index, 1);
    }
  }

  send(data) {
    if (this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(data);
    } else {
      console.warn('WebSocket connection is not open. Unable to send data.');
    }
  }

  reconnect() {
    setTimeout(() => {
      if (this.ws.readyState === WebSocket.CLOSED) {
        console.log('Attempting to reconnect WebSocket...');
        this.initConnection();
      }
    }, this.reconnectInterval);
  }

  close() {
    if (this.ws) {
      this.ws.close();
    }
  }
}

这个ReconnectingWebSocket Class封装了原生的WebSocket API,并提供了以下功能:

  • 通过onoff方法注册和注销事件处理程序。
  • 通过send方法发送消息。
  • 在连接关闭时自动尝试重新连接。
  • 提供了一个close方法来手动关闭连接。

使用封装后的WebSocket Class

使用ReconnectingWebSocket Class很简单。下面是一个示例,展示了如何在项目中使用这个Class

const ws = new ReconnectingWebSocket('wss://example.com/ws');

ws.on('open', () => {
  console.log('WebSocket connection opened.');
  ws.send('Hello, server!');
});

ws.on('message', (event) => {
  console.log('Received message:', event.data);
});

ws.on('close', () => {
  console.log('WebSocket connection closed.');
});

ws.on('error', (error) => {
  console.error('WebSocket error:', error);
});

在这个示例中,我们首先创建了一个新的ReconnectingWebSocket实例,并指定了要连接的WebSocket服务器的URL。然后,我们使用on方法注册了几个事件处理程序,分别用于处理连接打开、接收消息、连接关闭和错误事件。最后,我们在连接打开时发送了一条消息给服务器。

如果WebSocket连接因为某种原因断开了,ReconnectingWebSocket Class会自动尝试重新连接,并在连接重新打开后继续发送和接收消息。

另一个版本的完整封装

1.定义一个websocket类

/*
* 1.没连接到ws服务器的时候要不停的重连
* 2.重连的时候保证实例只有一个通道
*/
import {Message} from 'element-ui'
//params:{
//  path:string//sw地址
//  onmessage:function
//}
export class WhrWebSocket {
    constructor(params) {
      //只有params这个参数必须卸载constructor方法里,其他的实例属性可以写在外面
      // 比如 socket = null
        this.socket = null
        this.params = params
        this.j = 0 //websocket重连次数
        this.i = 0//发送信息次数
        if ('WebSocket' in window) {
            this.init(params)
        } else {
            Message({
                message: "浏览器不支持,请换浏览器再试",
                type: "error"
            });
        }
    }

    init(params) {
        console.log("init方法开始")
        if (params.path) {
            this.path = params.path
        } else {
            throw new Error('参数socket服务器地址path必须存在')
        }

        this.socket = new WebSocket(this.path)

        this.socket.onopen = () => {
            
            console.log("连接开启")
        }
        this.socket.onclose = () => {
            this.j = 0
            console.log("连接关闭")
            this.reconnect()
        }
        this.socket.onerror = () => {
            this.j = 0
            console.log("连接错误")
            
        }
       
        this.socket.onmessage = params.onmessage || this.getMessage


    }

    getMessage(msg) {
        console.log("收到的消息", msg)
        return msg
    }

    send(data) {
        let s = null
        try {
            if (this.socket.readyState == 1) {
                this.i = 0
                clearTimeout(s)
                this.socket.send(data)
                console.log("发送成功" + data)
            } else {
                if (this.i <= 10) {
                    console.log(this.socket.readyState)
                    ++this.i
                    // this.send(data)
                    s = setTimeout(() => {
                        this.send(data)
                    }, 100 * this.i)
                } else {
                    this.i = 0
                    clearTimeout(s)
                }
            }
        } catch (e) {
            console.log(e)

        }
    }
  close() {
        clearTimeout(this.time)
        this.socket.close(1000, '手动关闭')
        console.log("调用关闭")
    }
    reconnect() {
        this.j++
        //1.开始重连
        //2.如果连接不成功要继续重连
        if(this.j>1){
            return;
        }else {
            if (this.socket.readyState == 1 || this.socket.readyState == 0) {
                // this.lock = false
                // clearTimeout(s)
                return false
            } else {
                console.log('开始重连')
                this.time = setTimeout(() => {
                    this.init(this.params)
                }, 5000)
            }
        }
    }
}

2.用法

//创建
this.socket = new WhrWebSocket({
        path: this.path,
        onmessage: function (msg) {
          console.log(msg)                 
      })
//手动关闭
this.socket.close()

相关文章
websocket封装带心跳和重连机制(vue3+ts+vite)
websocket封装带心跳和重连机制(vue3+ts+vite)
1891 0
|
3月前
|
前端开发 JavaScript API
赶快收藏!全网最佳websocket封装:完美支持断网重连、自动心跳!
【8月更文挑战第17天】赶快收藏!全网最佳websocket封装:完美支持断网重连、自动心跳!
79 3
赶快收藏!全网最佳websocket封装:完美支持断网重连、自动心跳!
|
6月前
|
前端开发
告别屎山!!!WebSocket 的极致封装, 写好代码竟如此简单
告别屎山!!!WebSocket 的极致封装, 写好代码竟如此简单
223 0
|
JavaScript
websocket | 浅浅的封装一下
在写websocket的时候,很多页面都需要使用,每个页面重复写,太麻烦,于是先浅浅的封装一下。
|
开发框架 前端开发 网络协议
服务器开发- Asp.Net Core中的websocket,并封装一个简单的中间件
服务器开发- Asp.Net Core中的websocket,并封装一个简单的中间件
487 8
|
JavaScript
vue websocket组件封装
vue websocket组件封装
248 0
|
4月前
|
前端开发 网络协议 JavaScript
在Spring Boot中实现基于WebSocket的实时通信
在Spring Boot中实现基于WebSocket的实时通信
|
18天前
|
开发框架 前端开发 网络协议
Spring Boot结合Netty和WebSocket,实现后台向前端实时推送信息
【10月更文挑战第18天】 在现代互联网应用中,实时通信变得越来越重要。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为客户端和服务器之间的实时数据传输提供了一种高效的解决方案。Netty作为一个高性能、事件驱动的NIO框架,它基于Java NIO实现了异步和事件驱动的网络应用程序。Spring Boot是一个基于Spring框架的微服务开发框架,它提供了许多开箱即用的功能和简化配置的机制。本文将详细介绍如何使用Spring Boot集成Netty和WebSocket,实现后台向前端推送信息的功能。
204 1
|
23天前
|
前端开发 Java C++
RSocket vs WebSocket:Spring Boot 3.3 中的两大实时通信利器
本文介绍了在 Spring Boot 3.3 中使用 RSocket 和 WebSocket 实现实时通信的方法。RSocket 是一种高效的网络通信协议,支持多种通信模式,适用于微服务和流式数据传输。WebSocket 则是一种标准协议,支持全双工通信,适合实时数据更新场景。文章通过一个完整的示例,展示了如何配置项目、实现前后端交互和消息传递,并提供了详细的代码示例。通过这些技术,可以大幅提升系统的响应速度和处理效率。
|
3月前
|
开发框架 网络协议 Java
SpringBoot WebSocket大揭秘:实时通信、高效协作,一文让你彻底解锁!
【8月更文挑战第25天】本文介绍如何在SpringBoot项目中集成WebSocket以实现客户端与服务端的实时通信。首先概述了WebSocket的基本原理及其优势,接着详细阐述了集成步骤:添加依赖、配置WebSocket、定义WebSocket接口及进行测试。通过示例代码展示了整个过程,旨在帮助开发者更好地理解和应用这一技术。
234 1