You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SSE或WebSockets实现特定间隔的单向服务器到客户端数据传输?

定时单向服务器推送需求:SSE、WebSocket与替代方案解析

1. 能否用SSE实现?当然可以

你之前的误解是SSE必须持续发送数据,但实际上SSE只是保持HTTP长连接,服务器完全可以自主控制发送时机——只有在预定义间隔或触发条件满足时才推送消息,平时连接保持空闲即可。

服务器端实现示例(Node.js/Express)

const express = require('express');
const app = express();
const { EventEmitter } = require('events');

// 模拟业务事件触发源
const dataTrigger = new EventEmitter();

app.get('/sse', (req, res) => {
  // 设置SSE核心响应头
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.flushHeaders(); // 立即发送头信息建立长连接

  // 方案1:按预定义间隔推送(示例:每5分钟)
  const intervalTimer = setInterval(() => {
    const payload = JSON.stringify({
      type: 'interval',
      message: '定时推送内容',
      timestamp: new Date().toISOString()
    });
    res.write(`data: ${payload}\n\n`); // 遵循SSE消息格式
  }, 300000);

  // 方案2:特定业务条件触发推送
  const handleTrigger = (customData) => {
    const payload = JSON.stringify({
      type: 'triggered',
      data: customData,
      timestamp: new Date().toISOString()
    });
    res.write(`data: ${payload}\n\n`);
  };
  dataTrigger.on('new-business-data', handleTrigger);

  // 客户端断开连接时清理资源
  req.on('close', () => {
    clearInterval(intervalTimer);
    dataTrigger.off('new-business-data', handleTrigger);
    res.end();
  });
});

// 模拟业务逻辑触发推送(例如后台操作触发)
app.post('/trigger-push', (req, res) => {
  dataTrigger.emit('new-business-data', { content: '业务事件触发的推送内容' });
  res.sendStatus(200);
});

app.listen(3000);

客户端实现

const sse = new EventSource('/sse');
sse.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('收到SSE推送:', data);
};

// 可选:连接中断自动重连
sse.onerror = () => {
  console.log('SSE连接中断,尝试重连...');
  sse.close();
  setTimeout(() => {
    sse = new EventSource('/sse');
  }, 3000);
};

2. WebSocket是否是更优方案?视场景而定

WebSocket是双向通信协议,如果你当前需求仅为单向定时推送,它并不是更优选择——SSE基于HTTP协议,实现更简单、资源消耗更低,且天然支持单向推送。

但如果你的业务未来可能需要双向交互(例如客户端向服务器发送指令),WebSocket会更灵活。以下是WebSocket实现定时推送的示例:

服务器端示例(Node.js/ws库)

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
const { EventEmitter } = require('events');

const dataTrigger = new EventEmitter();

wss.on('connection', (ws) => {
  // 定时推送逻辑
  const intervalTimer = setInterval(() => {
    ws.send(JSON.stringify({
      type: 'interval',
      message: 'WebSocket定时推送',
      timestamp: new Date().toISOString()
    }));
  }, 300000);

  // 触发式推送逻辑
  const handleTrigger = (data) => {
    ws.send(JSON.stringify({
      type: 'triggered',
      data: data
    }));
  };
  dataTrigger.on('new-data', handleTrigger);

  // 客户端断开时清理资源
  ws.on('close', () => {
    clearInterval(intervalTimer);
    dataTrigger.off('new-data', handleTrigger);
  });
});

客户端示例

const ws = new WebSocket('ws://localhost:8080');
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('收到WebSocket推送:', data);
};

ws.onerror = (error) => {
  console.error('WebSocket连接错误:', error);
};

3. 替代方案:HTTP Polling与Long Polling

如果你的应用需要兼容极旧浏览器(如IE),或者无法使用长连接技术,可以考虑这两种方案:

HTTP Polling(普通轮询)

客户端每隔固定时间主动向服务器发起请求,服务器立即返回结果(无论是否有新数据)。优点是实现最简单,兼容性拉满;缺点是频繁请求会浪费带宽和服务器资源。

// 客户端示例
setInterval(async () => {
  const response = await fetch('/check-updates');
  const data = await response.json();
  if (data.hasUpdate) {
    console.log('轮询到新数据:', data.content);
  }
}, 300000);

Long Polling(长轮询)

客户端发起请求后,服务器挂起连接,直到有新数据或超时才返回;客户端收到响应后立即重新发起请求。相比普通轮询,它减少了请求次数,但服务器需要维护挂起的连接,资源消耗比SSE高。

// 客户端示例
const longPoll = async () => {
  try {
    const response = await fetch('/long-poll', { signal: AbortSignal.timeout(60000) });
    const data = await response.json();
    console.log('长轮询收到数据:', data);
  } catch (error) {
    console.log('长轮询超时/出错,重新发起请求');
  } finally {
    longPoll(); // 立即重新发起请求
  }
};
longPoll();

方案选择总结

  • 优先选SSE:仅单向推送需求,实现简单、资源消耗低,原生支持重连机制。
  • 选WebSocket:未来有双向交互需求,或需要传输二进制数据。
  • 选Long Polling:必须兼容IE等不支持SSE的旧浏览器。
  • 尽量避免普通HTTP Polling:资源浪费严重,仅在极端简单场景下使用。

内容的提问来源于stack exchange,提问作者sanjeevrcs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 07:38:13