所谓的SSE(Sever-Sent Event),就是浏览器向服务器发送了一个HTTP请求,保持长连接,服务器不断单向地向浏览器推送“信息”,这么做是为了节省网络资源,不用一直发请求,建立新连接。
可参考简单的websocket封装
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]) }
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;
以上为个人经验,希望对您有所帮助。