在现代 Web 应用程序中,即时通讯已经成为了一个必要的功能。而传统的轮询方式不仅效率低下,而且对服务器的负担也很大。在这种情况下,Server-Sent Events (SSE) 技术应运而生,它可以实现服务器向客户端推送实时数据,而不需要客户端不断地向服务器发送请求。
SSE 的基本原理
SSE 是一种基于 HTTP 协议的服务器推送技术,通过使用 EventSource 对象,服务器可以向客户端发送实时数据。SSE 的基本原理如下:
- 客户端向服务器发送 HTTP 请求,请求的头部包含
Accept: text/event-stream
,这表示客户端希望接收 SSE 格式的数据。 - 服务器收到请求后,会创建一个持久连接,然后向客户端发送一条响应,响应头部包含
Content-Type: text/event-stream
。 - 服务器会不断地向客户端发送数据,每条数据都以
\n\n
结尾,表示一条完整的事件。 - 客户端通过监听 EventSource 对象的
onmessage
事件来接收数据,每当接收到一条数据,就会触发该事件。
使用 SSE 实现即时通讯
下面是一个使用 SSE 实现即时通讯的示例代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>SSE Demo</title> </head> <body> <div id="messages"></div> <form> <input type="text" id="message"> <button type="submit">发送</button> </form> <script> const eventSource = new EventSource('/sse'); const messages = document.getElementById('messages'); eventSource.onmessage = function(event) { const data = JSON.parse(event.data); messages.innerHTML += '<p>' + data.message + '</p>'; }; document.querySelector('form').addEventListener('submit', function(event) { event.preventDefault(); const message = document.getElementById('message').value; fetch('/message', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: message }) }); }); </script> </body> </html>
在上面的示例中,我们向服务器发送一个 /sse
的 SSE 请求,然后通过监听 onmessage
事件来接收服务器发送的数据。当用户在表单中输入一条消息并点击发送按钮时,我们会向服务器发送一个 POST 请求,然后服务器会将该消息发送给所有连接到 /sse
的客户端。
下面是服务器端的示例代码:
const http = require('http'); const server = http.createServer(function(req, res) { if (req.url === '/sse') { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); setInterval(function() { res.write('data: ' + JSON.stringify({ message: 'Hello, world!' }) + '\n\n'); }, 1000); } else if (req.url === '/message' && req.method === 'POST') { let body = ''; req.on('data', function(chunk) { body += chunk; }); req.on('end', function() { const data = JSON.parse(body); server.emit('message', data.message); res.end(); }); } else { res.writeHead(404); res.end(); } }); server.on('message', function(message) { server.clients.forEach(function(client) { client.write('data: ' + JSON.stringify({ message: message }) + '\n\n'); }); }); server.listen(3000);
在服务器端,我们先创建了一个 HTTP 服务器,然后监听 /sse
和 /message
路径的请求。当客户端连接到 /sse
时,我们会向客户端发送一条消息,然后每隔一秒钟发送一条消息。当客户端向 /message
发送一条 POST 请求时,我们会将该消息发送给所有连接到 /sse
的客户端。
总结
使用 SSE 技术可以实现高效的即时通讯功能,而且无需使用 WebSocket 等复杂的技术。当然,SSE 也有一些限制,例如只能发送文本数据,不支持双向通讯等。但是对于一些简单的应用场景,SSE 是一个不错的选择。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658bda87eb4cecbf2d122803