前端实现简单的sse封装方式(React hook Vue3)

 更新时间:2024年08月29日 09:27:25   作者:bigHead-  
这篇文章主要介绍了前端实现简单的sse封装方式(React hook Vue3),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

什么是SSE?

所谓的SSE(Sever-Sent Event),就是浏览器向服务器发送了一个HTTP请求,保持长连接,服务器不断单向地向浏览器推送“信息”,这么做是为了节省网络资源,不用一直发请求,建立新连接。

  • 优点:SSE和WebSocket相比,最大的优势是便利,服务端不需要第三方组件,开发难度低,SSE和轮询相比它不用处理很多请求,不用每次建立新连接,延迟低。
  • 缺点:如果客户端有很多需要保持很多长连接,这回占用大量内存和连接数。

封装简单的SSE,以React hook为例

可参考简单的websocket封装

新建sse.ts文件

import {useState, useRef, useEffect} from 'react'

const useSSE = (url: string) => {
    const source = useRef<EventSource | null>(null)
    //接收到的sse数据
    const [sseData, setSseData] = useState({})

    // sse状态
    const [sseReadyState, setSseReadyState] = useState({
        key: 0,
        value: '正在链接中',
    })

    const creatSource = () => {
        const stateArr = [
            {key: 0, value: '正在链接中'},
            {key: 1, value: '已经链接并且可以通讯'},
            {key: 2, value: '连接已关闭或者没有链接成功'},
        ]

        try {
            source.current = new EventSource(url)
            source.current.onopen = (_e) => {
                setSseReadyState(stateArr[source.current?.readyState ?? 0])
            }

            source.current.onerror = (e) => {
                setSseReadyState(stateArr[source.current?.readyState ?? 0])
            }
            source.current.onmessage = (e) => {
                setSseData({...JSON.parse(e.data)})
            }
        } catch (error) {
            console.log(error)
        }
    }

    const sourceInit = () => {
        if (!source.current || source.current.readyState === 2) {
            creatSource()
        }
    }

    //  关闭 WebSocket
    const closeSource = () => {
        source.current?.close()
    }

    //重连
    const reconnectSSE = () => {
        try {
            closeSource()
            source.current = null
            creatSource()
        } catch (e) {
            console.log(e)
        }
    }

    useEffect(() => {
        sourceInit()
    },[])

    return {
        sseData,
        sseReadyState,
        closeSource,
        reconnectSSE,
    }
}
export default useSSE

这里一共暴露出四个参数。

分别是 sseData(接收到的 sse数据)、sseReadyState(当前 sse状态)、closeSource(关闭 sse)、reconnectSSE(重连)。

通过这几个简单的参数能够覆盖一般场景的需要。

下面代码为使用方法

import React, { useState, useEffect } from 'react'
import useWebsocket from '../../tools/webSocket'
export default function () {
	const {sseData,sseReadyState, closeSource,reconnectSSE} = useSSE(url)

	useEffect(() => {
        console.log( '当前状态',sseReadyState)
    },[sseReadyState])

	useEffect(() => {
        console.log( '接收到的数据',sseData)
    }, [sseData])
}

使用vue3实现

import { ref } from "vue";

const useSSE = (url: string) => {
  const source = ref<EventSource | null>(null);

  //接收到的sse数据
  const sseData = ref({});

  // sse状态
  const readyState = ref({ key: 0, value: "正在链接中" });

  const creatSource = () => {
    const stateArr = [
      { key: 0, value: "正在链接中" },
      { key: 1, value: "已经链接并且可以通讯" },
      { key: 2, value: "连接已关闭或者没有链接成功" },
    ];

    try {
      source.value= new EventSource(url);
      source.value.onopen = (e) => {
        readyState.value = stateArr[source.value?.readyState ?? 0];
      };

      source.value.onerror = (e) => {
        readyState.value = stateArr[source.value?.readyState ?? 0];
      };
      source.value.onmessage = (e) => {
        e.data && (sseData.value = { ...JSON.parse(e.data) });
      };
    } catch (error) {
      console.log(error);
    }
  };

  const sourceInit = () => {
    if (!source.value|| source.value.readyState === 2) {
      creatSource();
    }
  };

  //  关闭 WebSocket
  const closeSource = () => {
    source.value?.close();
  };

  //重连
  const reconnectSSE = () => {
    try {
      closeSource();
      source.value= null;
      creatSource();
    } catch (e) {
      console.log(e);
    }
  };

  return {
    sseData,
    readyState,
    sourceInit,
    closeSource,
    reconnectSSE,
  };
};
export default useSSE;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue基本指令实例图文讲解

    Vue基本指令实例图文讲解

    这篇文章主要介绍了Vue基本指令实例图文讲解,文章将基本指令讲解的很清楚,有对于指令不太懂的同学可以跟着学习研究下
    2021-02-02
  • Vue条件渲染与循环渲染实战详解

    Vue条件渲染与循环渲染实战详解

    这篇文章给大家介绍Vue条件渲染与循环渲染的相关知识,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2026-03-03
  • 详解Vue的options

    详解Vue的options

    options顾名思义是选项的意思,或称为构造选项。是在创建vue实例时传入的参数,是一个对象。该对象包含哪些属性?每个属性都是什么含义?本篇文章就来带大家详细了解其中的奥秘
    2021-05-05
  • 浅谈vue实现数据监听的函数 Object.defineProperty

    浅谈vue实现数据监听的函数 Object.defineProperty

    本篇文章主要介绍了浅谈vue实现数据监听的函数 Object.defineProperty,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • 组件中多个el-upload存在导致上传图片失效的问题及解决

    组件中多个el-upload存在导致上传图片失效的问题及解决

    这篇文章主要介绍了组件中多个el-upload存在导致上传图片失效的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • vue+element实现手机号验证码注册的示例

    vue+element实现手机号验证码注册的示例

    本文主要介绍了vue+element实现手机号验证码注册的示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • vue3中reactive的对象清空所引发的问题解决方案(清空不了和清空之后再去赋值就赋值不了)

    vue3中reactive的对象清空所引发的问题解决方案(清空不了和清空之后再去赋值就赋值不了)

    在使用reactive定义的变量时,直接赋值会失去响应式,为了清空 filters并确保响应式,可以使用Object.assign({}, filters)或者遍历对象逐个清除属性,本文介绍vue3中reactive的对象清空所引发的问题解决方案(清空不了和清空之后再去赋值就赋值不了),感兴趣的朋友一起看看吧
    2025-02-02
  • Vue中sync修饰符分析原理及用法示例

    Vue中sync修饰符分析原理及用法示例

    在vue中,子组件如果想修改父组件的变量,一般做法是通过绑定事件的方法,父组件向子组件传递修改变量的方法,子组件触发修改变量的方法执行,这种方式中规中矩;另一种方法是使用sync修饰符,此方法可以减少很多代码量
    2022-08-08
  • vue后台管理如何配置动态路由菜单

    vue后台管理如何配置动态路由菜单

    这篇文章主要介绍了vue后台管理如何配置动态路由菜单,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Vue指令之v-for的使用说明

    Vue指令之v-for的使用说明

    这篇文章主要介绍了Vue指令之v-for的使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04

最新评论