前言
在 web 开发中,实时通信这个需求很常见,在传统的前后端交互中,通常都是前端通过轮询或者长轮询来实现实时通信,但这样会引起很多不必要的请求,严重拖累了服务器性能。
Server-sent Events (简称 SSE) 可以实现客户端与服务器的实时通信,利用浏览器默认存在的 EventSource 对象可以全双工地与已经建立的 http 长连接通信。SSE 数据传输只需要普通的 HTTP GET 请求,因此 SSE 也被称为 HTTP 流。
SSE 实现原理
SSE 的实现原理是在客户端发起一个简单的 HTTP GET 请求,服务器返回的是一个数据流,这个数据流通常是一个持续打开的 HTTP 连接,返回的数据格式是纯文本格式,基于标准化的 MIME 类型 text/event-stream,由 sever 端通过发送统一的格式化的消息来更新客户端,而客户端通过内置的浏览器对象的 onmessage 方法进行事件处理。
当客户端与服务器建立 SSE 连接后,如果连接一直保持开放状态,服务器就可以发送消息给客户端,客户端可以随时接收到信息而不需要刷新页面。当连接关闭后,客户端会自动重新连接,直到又建立了一个新的连接为止。SSE 连接的过程如下:
SSE 代码示例
下面是一个简单的 SSE 实现示例,通过 Node.js 服务端可实现将获取到的时间推送给客户端。
服务端代码:
const http = require('http'); http.createServer((req, res) => { console.log('server connected'); res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); setInterval(() => { const time = new Date().toLocaleTimeString(); const data = `data: ${time}\n\n`; res.write(data); }, 1000); }).listen(3000); console.log('SSE server started at http://localhost:3000');
客户端代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>SSE 实时通信示例</title> </head> <body> <h1>SSE 实时通信示例</h1> <hr> <div id="time"></div> <script> const eventSource = new EventSource('http://localhost:3000/'); eventSource.addEventListener('message', (event) => { const time = event.data; document.querySelector('#time').innerHTML = time; }); </script> </body> </html>
在服务端运行 node app.js(假设代码文件名称为 app.js),在浏览器中打开客户端代码,即可实现通过 SSE 实现实时通信。
总结
SSE 与 WebSocket 相比,SSE 需要的网络请求更少且网络负载更小,且不需要特殊的服务器配置。SSE 所传送的信息类型比 WebSocket 更简单,仅支持纯文本格式,而 WebSocket 可以支持任何格式的消息。但相对来说,SSE 更容易实现,不需要额外的库或者协议支持,而 WebSocket 需要额外的技术支持。
PS:需要注意的是,SSE 并不是所有浏览器都支持,所以在使用 SSE 时,需要做好浏览器兼容性问题。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b70f2dadd4f0e0fffa9195