将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)
1700 0
|
1月前
|
前端开发
告别屎山!!!WebSocket 的极致封装, 写好代码竟如此简单
告别屎山!!!WebSocket 的极致封装, 写好代码竟如此简单
109 0
|
8月前
|
JavaScript
websocket | 浅浅的封装一下
在写websocket的时候,很多页面都需要使用,每个页面重复写,太麻烦,于是先浅浅的封装一下。
|
11月前
|
JavaScript
vue websocket组件封装
vue websocket组件封装
215 0
|
开发框架 前端开发 网络协议
服务器开发- Asp.Net Core中的websocket,并封装一个简单的中间件
服务器开发- Asp.Net Core中的websocket,并封装一个简单的中间件
437 0
|
1月前
|
网络协议 前端开发 Java
SpringBoot 整合 WebSocket
WebSocket是基于TCP协议的一种网络协议,它实现了浏览器与服务器全双工通信,支持客户端和服务端之间相互发送信息。在有WebSocket之前,如果服务端数据发生了改变,客户端想知道的话,只能采用定时轮询的方式去服务端获取,这种方式很大程度上增大了服务器端的压力,有了WebSocket之后,如果服务端数据发生改变,可以立即通知客户端,客户端就不用轮询去换取,降低了服务器的压力。目前主流的浏览器都已经支持WebSocket协议了。
|
9天前
|
前端开发 JavaScript 安全
集成WebSocket在Spring Boot中可以用于实现实时的双向通信
集成WebSocket在Spring Boot中可以用于实现实时的双向通信
28 4
|
23小时前
|
监控 网络协议 Java
使用Spring Boot和WebSocket实现实时通信
使用Spring Boot和WebSocket实现实时通信
|
1天前
|
监控 前端开发 网络协议
如何使用Spring Boot实现WebSocket通信
如何使用Spring Boot实现WebSocket通信
|
4天前
|
Java
springboot集成websocket
springboot集成websocket
7 0