Server-sent Events(SSE) 如何实现断点续传的推送功能
在前端开发中,经常会遇到需要从后台服务端主动推送数据给前端的场景,这时候我们可以使用 Server-sent Events (SSE) 作为一种解决方案。SSE 采用了 HTTP 长轮询的机制,服务器在一定时间内保持长连接,通过 HTTP 技术,将数据实时推送给前端,同时支持断点续传,提高了数据传输的效率以及稳定性。
SSE 技术的实现
SSE 是浏览器内置的 API,通过在 HTML 中引入一个指定的 MIME 类型(text/event-stream),从而发起一个 SSE 请求。服务端响应 SSE 请求后,长连接将保持打开状态,随着时间的流逝,服务端会主动向客户端发送一个或者多个序列化的事件。每个事件包含一个单一的数据字段,可以根据自己的需求指定事件名称。
下面是一个简单的例子:
let eventSource = new EventSource('/api/sse') eventSource.addEventListener('myevent', event => { let data = JSON.parse(event.data) console.log(data) })
上述代码中,通过 new EventSource 创建了一个 SSE 连接,指定了后台服务端的地址。通过函数 addEventListener,我们可以监听到特定事件(这里是 myevent),一旦事件产生,我们可以通过 event.data 获取数据,并进行处理。
最简单的 SSE 请求响应过程如下图所示:
SSE 技术如何实现断点续传
SSE 技术的断点续传实现与 Range Header 强相关,Range Header 是指 HTTP 头部字段 Range,用于请求资源的片段,以实现只请求资源的一部分。通过 SSE 和 Range Head 我们可以实现将大的数据分成多个小的数据块进行传输,出现网络中断等情况可以从中断的位置继续上传数据块,提高了数据传输的可靠性。
我们可以通过在 HTTP 头部添加 Range 来实现断点续传。服务器端读取 Range 并按照 Range 请求所请求的信息,发送指定内容的数据块。前端需要记录数据块的接收情况,并对未接收完整的数据块新增 Range 请求,直到所有数据块被完全接收,并进行合并。
下面是一个简单的 SSE 断点续传代码的示例:
服务端
-- -------------------- ---- ------- ------------------------ -------- ----- ---- - --- ----- - ------------------------------- --- -------- - ---------- --- ----- - ----------------- -- ---------- --- --------- - ----------------------- -------------- --- ----- - ---------------------- --- --- --- - ------------ - ---------------------- --- - -------- - - --- --------- - ---- - ------ - - --- ---- - --------------------------------------- ------- ----- --- ---- - - ---------------- ------ ----------------------------- ---------------- -------- ----------------- ---------- --------------- ----------- - ------------------ ----- -------------- --- -------- --- --------- - ---------- ---------------------- -- -- - ----------------------- ------------------- -------- -- -------- - -------------- -- - --- ----------- - ---------- - --------- -- ------------ - ----- - ----------------------- ------------------- -- -------- -------- - ---- - ---------------- ------- --- ---------- ----------- -------------- - ------------- - -- ----- --
在服务端代码中,我们通过 header.range 来获取 Range 请求的 start 和 end,然后读取特定区间的数据进行相应。最后定时向前端发送 SSE 请求(res.write),利用 SSE 的长连接机制与 Range 头部实现断点续传。
客户端
let eventSource = new EventSource('/largefile') eventSource.onmessage = event => { let data = JSON.parse(event.data) console.log(data) }
在客户端代码中,我们只需要接收 SSE 返回的数据,并进行相应处理即可。
思考与总结
通过使用 SSE 与 Range Header,我们可以运用断点续传机制实现数据块的高效传输以及传输过程中网络不稳定等问题的保证。当然,实现断点续传的过程中需要注意数据分块和分段合成的问题,以及对数据的格式和处理方式等问题的考虑。
通过学习与实践 SSE 断点续传的技术,能够更好的掌握 HTTP 长连接的机制,以及大数据量的传输的处理,使得前端开发和后端交互更加高效和稳定。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6519458695b1f8cacd1763cd