简介
SSE(Server-Sent Events)是一种 HTML5 的 API,它允许浏览器从服务器接收事件流,以此来实现与后台的实时双向通信。这比起传统的轮询或长轮询技术,在效率和带宽利用率上有显著提升。在前端开发中,SSE 已经成为了一种非常有用的技术。
在本文中,我们将详细介绍如何使用 SSE 在前端中实现与后台的双向通信,并提供示例代码和深入讲解。
SSE 的工作原理
SSE 最大的特点就是实时双向通信。它是通过一个长连接(在 HTTP 上使用长连接也称为长轮询)来实现的。这个长连接一旦建立,就可以一直保持连接状态,直到某一方终止连接。
在浏览器中,我们可以通过 EventSource 来接收从服务器发送过来的事件流。当服务器有新事件发生时,我们可以通过事件回调函数来处理这些事件,从而实现实时通信。
当然,SSE 一般还需要在后台编写一些代码来实现它。这个流程我们将在接下来的部分进行详细介绍。
建立 SSE 连接
在前端页面中,要建立 SSE 连接很简单,我们只需要使用 EventSource 的构造函数调用即可:
const sse = new EventSource('/sse');
这里的 /sse
就是我们需要与后台建立 SSE 连接的地址。接下来我们需要在后台编写相关代码来支持 SSE 通信。
在后台实现 SSE
在后台实现 SSE 首先需要了解一些基础知识。SSE 是基于 HTTP 协议的,所以我们需要使用 Node.js 来编写后台代码实现 SSE 连接。
下面是后台代码的主要逻辑:
-- -------------------- ---- ------- ----- ---- - ---------------- ----- -- - -------------- -------------------------- ----- ---- - -- -------- --- ------- - ------------------ - --------------- -------------------- ---------------- ----------- ------------- ------------- --- -------------------- -- - ---------------- - - ---------- - -------- -- ------ ----------------------------------- -------- -- - ----------------------- ---------- --- - ---- - ------------------ ---------------- -------------- --------------------------------- - ---------------- - ----------------
这段代码的主要作用是监听 HTTP 请求,如果请求地址是 /sse
,则使用正确的 MIME 类型设置响应头,以确保浏览器收到请求时能正确解析 SSE。此外,在响应头中还需要设置 Cache-Control
和 Connection
,以避免浏览器缓存和实现长连接。
接下来在代码中添加一个定时器,每秒钟向客户端发送一个事件流,并通过 data:
标签指定事件流的数据格式。要注意的是,在每条事件流末尾都必须加上 \n\n
来分隔每一条事件,并且在发送完成后调用 res.flush()
来确保事件流能够实时推送。
最后,我们需要监听客户端的关闭事件,以便及时释放资源。
这就是一个简单的 SSE 后台代码的实现。具体的实现方式会根据项目需求和技术栈不同而有所差异,在这里不再详述。
在前端接收事件流
在前端代码中,我们需要使用回调函数来处理后台传递过来的事件,使用 EventSource
的 onmessage
事件来处理接收到的事件。如下所示:
sse.onmessage = function(event) { console.log(event.data); };
上述代码将会在后端每秒钟发送一条事件流时,输出当前时间戳。在实际开发过程中,这个事件流的数据肯定是需要根据实际需求去定义的。这里的目的是简单演示如何处理后台传递的事件。
结论
SSE 是一种十分有用的技术,它可以帮助我们实现实时双向通信的功能。在前端代码实现中,我们需要使用 EventSource
来建立 SSE 连接,并在事件回调函数中处理后台传递过来的数据。在后台代码实现中,我们需要设置正确的 MIME 类型和响应头,使用定时器发送事件流,以及监听客户端的关闭事件等。
以上就是 SSE 的基本使用方法,希望本文能对你有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/670e32ea5f55128102601247