前端对WebSocket进行封装,并建立心跳监测

WebSocket的介绍:

WebSocket 是一种在客户端和服务器之间进行全双工、双向通信的协议。它是基于 HTTP 协议,但通过升级(HTTP 升级请求)将连接转换为 WebSocket 协议,从而提供更高效的实时数据交换。

WebSocket 的特点:

  1. 双向通信:与传统的 HTTP 协议只能从客户端向服务器发送请求并等待响应不同,WebSocket 可以实现服务器主动向客户端推送数据,支持双向通信。

  2. 持久连接:WebSocket 连接建立后,它是持久的,可以在不重新建立连接的情况下进行多次数据交换。相比于传统的 HTTP 每次请求都需要建立新的连接,WebSocket 减少了很多开销。

  3. 实时性:由于 WebSocket 的全双工通信特性,它非常适合需要实时更新数据的应用场景,如即时聊天、在线游戏、股票行情等。

  4. 低延迟:WebSocket 建立连接后,数据可以随时在客户端和服务器之间交换,而且没有 HTTP 协议中的请求和响应过程,因此延迟非常低。

  5. 协议格式:WebSocket 协议位于应用层与 TCP 层之间,它的标准端口是 80(非加密连接)和 443(加密连接)。

WebSocket 工作原理:

  1. 连接建立 :客户端发起一个 HTTP 请求,并通过 HTTP 升级请求(Upgrade 请求头)向服务器请求升级协议为 WebSocket。
  2. 协议升级 :如果服务器支持 WebSocket 协议,它会响应 101 Switching Protocols,并升级为 WebSocket 协议。此时,WebSocket 连接建立成功。
  3. 数据交换:一旦连接建立,客户端和服务器可以在同一连接上发送和接收消息,直到连接被关闭。
  4. 连接关闭 :无论是客户端还是服务器,都可以主动发起关闭连接。连接关闭时,双方会互相发送关闭帧(Close Frame)来通知对方。

项目需求:

由于最近项目上的大屏接口要换成WebSocket进行实时数据展示,于是需要对WebSocket进行封装,主要目标是要实现与后端持续保持心跳连接,不要让WebSocket中断;例如每10秒就要和后端通讯一次,发送和后端沟通好固定的心跳标识符,后端拿到心跳标识符就会持续保持连接,如果一直没有收到前端返回的心跳标识符,那么就会中断WebSocket的连接。

源代码

javascript 复制代码
export default class WebSocketClient {
    constructor(url, callback) {
        this.url = url;           // WebSocket 服务器的 URL
        this.callback = callback; // 回调方法,用于接收数据
        this.ws = null;           // WebSocket 实例
        this.heartbeatInterval = 20000; // 心跳间隔(20秒)
        this.pingTimeout = 10000;        // ping 超时时间(10秒)
        this.heartbeatTimer = null;      // 用于存储心跳定时器
        this.pingTimer = null;           // 用于存储 ping 超时定时器
        this.reconnect = true;          // 用于判断是否需要重连
    }

    // 启动 WebSocket 连接
    start() {
        this.ws = new WebSocket(this.url);

        this.ws.onopen = () => {
            console.log("WebSocket连接成功");
            this.reconnect = true; // 连接成功,允许重连
            this.startHeartbeat(); // 连接成功后开始心跳
        };

        this.ws.onmessage = (event) => {
            this.callback(event.data); // 调用回调方法
        };

        this.ws.onerror = (error) => {
            console.error("WebSocket异常:", error);
        };

        this.ws.onclose = (event) => {
            console.log("WebSocket关闭.");
            clearInterval(this.heartbeatTimer); // 清除心跳定时器
            clearTimeout(this.pingTimer); // 清除 ping 超时定时器

            if (this.reconnect && event.code !== 1000) { // 如果是非正常关闭,进行重连
                console.log("尝试重新连接...");
                setTimeout(() => {
                    this.start(); // 5秒后重新连接
                }, 5000);
            }
        };
    }

    // 发送数据到服务器
    send(message) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(message);
        } else {
            console.error("消息发送失败.");
        }
    }

    // 启动心跳机制
    startHeartbeat() {
        this.heartbeatTimer = setInterval(() => {
            if (this.ws.readyState === WebSocket.OPEN) {
                this.send(JSON.stringify({ type: "heartbeat", data: "pong" })); // 与后端约定的心跳标识符,用于保持持续连接
            }
        }, this.heartbeatInterval);

        // 设置 ping 超时机制
        this.pingTimer = setTimeout(() => {
            if (this.ws.readyState !== WebSocket.OPEN) {
                console.error("超时关闭连接.");
                this.ws.close();
            }
        }, this.pingTimeout);
    }

    // 主动关闭连接
    close() {
        this.reconnect = false;  // 主动关闭时不再进行重连
        if (this.ws) {
            this.ws.close(1000, 'Closed by client'); // 主动关闭时使用 code 1000 表示正常关闭
        }
    }
}

用法

javascript 复制代码
import WebSocketClient from '@/request/ws'

export default {
    data(){
        return{
            wsClient:null
        }
    },
    mounted(){
        this.wsClient = new WebSocketClient('ws://192.168.31.21:8090/ws', this.getWSMessage);
        this.wsClient.start()
    },
    methods:{
        getWSMessage(data){
            console.log(data,'ddddddddddddddd')
        },
        sendMessage(){
            let obj = { type: "555", data: "111111" }
            this.wsClient.send(JSON.stringify(obj))
        }

    },
    beforeDestroy() {
        this.wsClient.close()
    }
}
相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊4 小时前
jwt介绍
前端
爱敲代码的小鱼4 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax