什么是 SSE?
SSE(Server-Sent Events)是一种服务器推送技术,它通过简单的 HTTP 连接,让服务器可以推送实时数据到客户端,实现了服务器到客户端的单向通信。SSE 的特点是基于纯文本(text/event-stream)传输,不需要创建额外的套接字,可以实现非常高效的数据传输。SSE 可以实现较为简单的实时通信,适用于不需要双向通信的场景。
什么是 WebSocket?
WebSocket 是另一种服务端推送技术,它是一种全双工的通信协议,在浏览器与服务器之间创建了一个基于 TCP 的长连接,实现了双向通信。WebSocket 协议与 HTTP 协议不同,是一个独立的协议,它使用“握手协议”来处理连接,并在连接建立后,会保持打开状态,直到客户端或服务器决定关闭连接。WebSocket 可以实现较为复杂的实时通信,适用于需要双向通信的场景。
SSE 与 WebSocket 的对比
虽然 SSE 和 WebSocket 都可以实现实时通信,但是它们之间有许多不同之处。下面是它们的优缺点对比:
SSE 的优点
- 相对 WebSocket 来说,使用 SSE 比较简单,只需打开一个 HTTP 连接即可。
- SSE 不需要额外的套接字,可以实现非常高效的数据传输。
- SSE 可以实现相对较简单的单向实时通信,适合一些简单的场景,例如更新数据、新闻发布等。
SSE 的缺点
- SSE 是单向通信,客户端只能接收服务器的推送消息,无法发送消息到服务器。
- SSE 不支持二进制数据传输。
- SSE 连接一旦建立,无法更改。如果需要获取新的 SSE 数据,必须关闭连接并重新建立新的连接。
- SSE 的消息格式只能是纯文本,无法进行压缩。
WebSocket 的优点
- WebSocket 支持双向通信,客户端和服务器可以互相推送消息,并且消息格式可以是文本或二进制。
- WebSocket 的连接是基于 TCP 的长连接,连接建立后可以一直保持开启状态,可以实现比 SSE 更低的延迟和更高的吞吐量。
- WebSocket 可以自定义协议,可以适用于多种场景。
- WebSocket 的连接一旦建立,可以自由切换数据传输方向,实现更灵活的实时通信。
WebSocket 的缺点
- WebSocket 的开发相对 SSE 来说较为复杂,并且需要更多的服务器资源。
- WebSocket 的连接建立需要进行额外的握手协议,会产生一定的网络负载。
- WebSocket 的消息格式可以是文本或二进制,对于一些安全性要求比较高的场景,需要进行额外的安全处理。
SSE 与 WebSocket 的使用场景
由于 SSE 与 WebSocket 功能和性能存在不同,因此在实际的应用场景中,需要根据实际需求来选择合适的技术。下面是 SSE 和 WebSocket 的使用场景:
SSE 的使用场景
- 相对较为简单的实时通信场景,例如新闻发布、在线股票行情、聊天室等。
- 对数据实时性要求较高,但不需要双向通信的场景。
- 对服务器资源要求较低的场景。
WebSocket 的使用场景
- 对实时性要求较高并且需要双向通信的场景。
- 需要自定义协议的场景。
- 对服务器资源要求较高的场景。
SSE 和 WebSocket 的使用示例
下面是 SSE 和 WebSocket 的使用示例。
SSE 的使用示例
// javascriptcn.com 代码示例 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>SSE 示例</title> </head> <body> <h1>SSE 示例</h1> <div id="result"></div> <script> var source = new EventSource("/api/sse"); source.onmessage = function(event) { document.getElementById("result").innerHTML = event.data; }; </script> </body> </html>
服务端代码:
// javascriptcn.com 代码示例 const http = require('http'); const server = http.createServer((req, res) => { if (req.url === '/api/sse') { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); res.write('event: message\n'); res.write('data: hello world\n\n'); setInterval(() => { res.write('event: message\n'); res.write('data: ' + new Date().toLocaleTimeString() + '\n\n'); }, 1000); } else { res.writeHead(404); res.end(); } }); server.listen(3000);
WebSocket 的使用示例
// javascriptcn.com 代码示例 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>WebSocket 示例</title> </head> <body> <h1>WebSocket 示例</h1> <button id="btn-connect">连接</button> <button id="btn-disconnect">断开</button> <div id="result"></div> <script> var ws; document.getElementById("btn-connect").addEventListener("click", function() { ws = new WebSocket("ws://localhost:3000/ws"); ws.onopen = function() { document.getElementById("result").innerHTML = "已连接"; }; ws.onmessage = function(event) { document.getElementById("result").innerHTML = event.data; }; }); document.getElementById("btn-disconnect").addEventListener("click", function() { if (ws) { ws.close(); } }); </script> </body> </html>
服务端代码:
// javascriptcn.com 代码示例 const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 3000 }); wss.on('connection', function(ws) { ws.send('连接成功'); setInterval(() => { ws.send(new Date().toLocaleTimeString()); }, 1000); });
总结
SSE 和 WebSocket 都是实现实时通信的技术,但是它们之间存在很多不同之处。在选择使用 SSE 还是 WebSocket 的时候,需要根据实际的需求来进行选择。如果需要双向通信,并且对实时性要求较高,建议使用 WebSocket;如果只是需要单向通信,并且对服务器资源要求较低,可以考虑使用 SSE。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654b5fe17d4982a6eb53d235