什么是sse?
所谓的sse(sever-sent event),就是浏览器向服务器发送了一个http请求,保持长连接,服务器不断单向地向浏览器推送“信息”,这么做是为了节省网络资源,不用一直发请求,建立新连接。
- 优点:sse和websocket相比,最大的优势是便利,服务端不需要第三方组件,开发难度低,sse和轮询相比它不用处理很多请求,不用每次建立新连接,延迟低。
- 缺点:如果客户端有很多需要保持很多长连接,这回占用大量内存和连接数。
封装简单的sse,以react hook为例
可参考
新建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;
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论