SSE(Server-Sent Events)是一种基于 HTTP 的服务器推送技术,可以实现服务器向客户端推送数据,而不需要客户端发送请求。SSE 的优点在于实时性好,适用于需要实时更新数据的场景,如股票行情、聊天室等。但是,SSE 也存在一些限制,本文将介绍这些限制,并提供解决方法。
SSE 的限制
单向传输
SSE 是一种单向传输协议,只能由服务器向客户端传输数据,无法由客户端向服务器发送数据。因此,无法实现客户端与服务器之间的双向通信。
连接限制
SSE 连接数受限,一般浏览器限制为 6-8 个连接。如果连接数超过限制,将会导致连接失败或延迟。
浏览器兼容性
SSE 并没有被所有浏览器广泛支持。目前,SSE 在现代浏览器中得到了很好的支持,但在一些老旧的浏览器中可能存在兼容性问题。
解决方法
Websocket
Websocket 是一种双向通信协议,可以实现客户端与服务器之间的双向通信。与 SSE 不同的是,Websocket 是一种双向传输协议,可以由客户端向服务器发送数据。因此,Websocket 可以解决 SSE 单向传输的限制。
Websocket 的优点在于实时性好,适用于需要实时更新数据的场景,如股票行情、聊天室等。但是,Websocket 也存在一些限制,如浏览器兼容性问题。
Comet
Comet 是一种基于 HTTP 的服务器推送技术,可以实现服务器向客户端推送数据。与 SSE 不同的是,Comet 是一种双向传输协议,可以由客户端向服务器发送数据。因此,Comet 可以解决 SSE 单向传输的限制。
Comet 的优点在于兼容性好,适用于需要实时更新数据的场景,如股票行情、聊天室等。但是,Comet 也存在一些限制,如连接数受限、性能问题等。
Ajax 轮询
Ajax 轮询是一种基于 Ajax 的服务器推送技术,可以实现服务器向客户端推送数据。与 SSE 不同的是,Ajax 轮询是一种双向传输协议,可以由客户端向服务器发送数据。因此,Ajax 轮询可以解决 SSE 单向传输的限制。
Ajax 轮询的优点在于兼容性好,适用于需要实时更新数据的场景,如股票行情、聊天室等。但是,Ajax 轮询也存在一些限制,如连接数受限、性能问题等。
示例代码
SSE 示例代码
// javascriptcn.com 代码示例 // 服务器端代码 const express = require('express'); const app = express(); app.use(express.static('public')); app.get('/sse', (req, res) => { res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); setInterval(() => { const data = `data: ${new Date().toISOString()}\n\n`; res.write(data); }, 1000); }); app.listen(3000, () => { console.log('Server started on port 3000'); });
// 客户端代码 const source = new EventSource('/sse'); source.addEventListener('message', event => { console.log(event.data); });
Websocket 示例代码
// javascriptcn.com 代码示例 // 服务器端代码 const express = require('express'); const app = express(); const http = require('http'); const server = http.createServer(app); const WebSocket = require('ws'); const wss = new WebSocket.Server({ server }); wss.on('connection', ws => { ws.on('message', message => { console.log(`Received message: ${message}`); ws.send(`Received message: ${message}`); }); setInterval(() => { const data = `Time: ${new Date().toISOString()}`; ws.send(data); }, 1000); }); server.listen(3000, () => { console.log('Server started on port 3000'); });
// javascriptcn.com 代码示例 // 客户端代码 const ws = new WebSocket('ws://localhost:3000'); ws.addEventListener('open', () => { console.log('Connected to server'); }); ws.addEventListener('message', event => { console.log(event.data); }); ws.addEventListener('close', () => { console.log('Disconnected from server'); });
Ajax 轮询示例代码
// javascriptcn.com 代码示例 // 服务器端代码 const express = require('express'); const app = express(); app.use(express.static('public')); app.get('/poll', (req, res) => { setInterval(() => { const data = new Date().toISOString(); res.send(data); }, 1000); }); app.listen(3000, () => { console.log('Server started on port 3000'); });
// javascriptcn.com 代码示例 // 客户端代码 function poll() { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText); setTimeout(poll, 1000); } }; xhr.open('GET', '/poll', true); xhr.send(); } poll();
总结
SSE 是一种基于 HTTP 的服务器推送技术,可以实现服务器向客户端推送数据,但是存在单向传输、连接限制和浏览器兼容性等限制。可以使用 Websocket、Comet 和 Ajax 轮询等技术解决这些限制。这些技术各有优缺点,可以根据具体的业务需求选择适合的技术。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6572f68bd2f5e1655dc0ccf3