什么是SSE?
所谓的SSE(Sever-Sent Event),就是浏览器向服务器发送了一个HTTP请求,保持长连接,服务器不断单向地向浏览器推送“信息”,这么做是为了节省网络资源,不用一直发请求,建立新连接。
- 优点:SSE和WebSocket相比,最大的优势是便利,服务端不需要第三方组件,开发难度低,SSE和轮询相比它不用处理很多请求,不用每次建立新连接,延迟低。
- 缺点:如果客户端有很多需要保持很多长连接,这回占用大量内存和连接数。
封装简单的SSE,以React hook为例。 可参考简单的websocket封装
1. 新建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;
文章来源地址https://www.toymoban.com/news/detail-700724.html
文章来源:https://www.toymoban.com/news/detail-700724.html
到了这里,关于前端实现简单的sse封装(React hook Vue3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!