前端實(shí)現(xiàn)簡(jiǎn)單的sse封裝方式(React hook Vue3)
什么是SSE?
所謂的SSE(Sever-Sent Event),就是瀏覽器向服務(wù)器發(fā)送了一個(gè)HTTP請(qǐng)求,保持長(zhǎng)連接,服務(wù)器不斷單向地向?yàn)g覽器推送“信息”,這么做是為了節(jié)省網(wǎng)絡(luò)資源,不用一直發(fā)請(qǐng)求,建立新連接。
- 優(yōu)點(diǎn):SSE和WebSocket相比,最大的優(yōu)勢(shì)是便利,服務(wù)端不需要第三方組件,開發(fā)難度低,SSE和輪詢相比它不用處理很多請(qǐng)求,不用每次建立新連接,延遲低。
- 缺點(diǎn):如果客戶端有很多需要保持很多長(zhǎng)連接,這回占用大量?jī)?nèi)存和連接數(shù)。
封裝簡(jiǎn)單的SSE,以React hook為例
新建sse.ts文件
import {useState, useRef, useEffect} from 'react'
const useSSE = (url: string) => {
const source = useRef<EventSource | null>(null)
//接收到的sse數(shù)據(jù)
const [sseData, setSseData] = useState({})
// sse狀態(tài)
const [sseReadyState, setSseReadyState] = useState({
key: 0,
value: '正在鏈接中',
})
const creatSource = () => {
const stateArr = [
{key: 0, value: '正在鏈接中'},
{key: 1, value: '已經(jīng)鏈接并且可以通訊'},
{key: 2, value: '連接已關(guān)閉或者沒有鏈接成功'},
]
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()
}
}
// 關(guān)閉 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這里一共暴露出四個(gè)參數(shù)。
分別是 sseData(接收到的 sse數(shù)據(jù))、sseReadyState(當(dāng)前 sse狀態(tài))、closeSource(關(guān)閉 sse)、reconnectSSE(重連)。
通過這幾個(gè)簡(jiǎn)單的參數(shù)能夠覆蓋一般場(chǎng)景的需要。
下面代碼為使用方法
import React, { useState, useEffect } from 'react'
import useWebsocket from '../../tools/webSocket'
export default function () {
const {sseData,sseReadyState, closeSource,reconnectSSE} = useSSE(url)
useEffect(() => {
console.log( '當(dāng)前狀態(tài)',sseReadyState)
},[sseReadyState])
useEffect(() => {
console.log( '接收到的數(shù)據(jù)',sseData)
}, [sseData])
}使用vue3實(shí)現(xiàn)
import { ref } from "vue";
const useSSE = (url: string) => {
const source = ref<EventSource | null>(null);
//接收到的sse數(shù)據(jù)
const sseData = ref({});
// sse狀態(tài)
const readyState = ref({ key: 0, value: "正在鏈接中" });
const creatSource = () => {
const stateArr = [
{ key: 0, value: "正在鏈接中" },
{ key: 1, value: "已經(jīng)鏈接并且可以通訊" },
{ key: 2, value: "連接已關(guān)閉或者沒有鏈接成功" },
];
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();
}
};
// 關(guān)閉 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;總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue條件渲染與循環(huán)渲染實(shí)戰(zhàn)詳解
這篇文章給大家介紹Vue條件渲染與循環(huán)渲染的相關(guān)知識(shí),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2026-03-03
淺談vue實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽的函數(shù) Object.defineProperty
本篇文章主要介紹了淺談vue實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽的函數(shù) Object.defineProperty,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
組件中多個(gè)el-upload存在導(dǎo)致上傳圖片失效的問題及解決
這篇文章主要介紹了組件中多個(gè)el-upload存在導(dǎo)致上傳圖片失效的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
vue+element實(shí)現(xiàn)手機(jī)號(hào)驗(yàn)證碼注冊(cè)的示例
本文主要介紹了vue+element實(shí)現(xiàn)手機(jī)號(hào)驗(yàn)證碼注冊(cè)的示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
vue3中reactive的對(duì)象清空所引發(fā)的問題解決方案(清空不了和清空之后再去賦值就賦值不了)
在使用reactive定義的變量時(shí),直接賦值會(huì)失去響應(yīng)式,為了清空?filters并確保響應(yīng)式,可以使用Object.assign({},?filters)或者遍歷對(duì)象逐個(gè)清除屬性,本文介紹vue3中reactive的對(duì)象清空所引發(fā)的問題解決方案(清空不了和清空之后再去賦值就賦值不了),感興趣的朋友一起看看吧2025-02-02
vue后臺(tái)管理如何配置動(dòng)態(tài)路由菜單
這篇文章主要介紹了vue后臺(tái)管理如何配置動(dòng)態(tài)路由菜單,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04

