客户端用setInterval轮询Node.js获消息列表:是否有问题?HTTP2更优吗?
Hey David, great question—this is such a common dilemma when building real-time messaging features, so let’s break this down clearly.
First: Will Your Current Polling Approach Cause Serious Issues?
Short answer: Not necessarily for small-scale apps, but it will scale poorly and has inherent limitations. Here’s why:
- Wasted Bandwidth & Server Resources: 90% of those 5-second GET requests will probably return no new messages. Each request still carries HTTP overhead (headers, TCP handshake if you’re on HTTP1.1), and repeated execution of the same
session_idquery will eat into MongoDB’s CPU/memory over time—especially as your user count grows. - Latency: Users could wait up to 5 seconds to see a new message, which feels sluggish for real-time use cases like chat.
- Connection Limits: While modern browsers handle concurrent requests well, frequent polling can still strain server connection pools, especially if you’re on HTTP1.1 (which limits concurrent requests per domain).
It’s not a "critical" issue for early-stage apps, but it’s definitely a technical debt that will bite you as you scale.
HTTP2 vs. HTTP1.1 Polling: Is There a Significant Advantage?
Yes, but it’s important to set expectations: HTTP2 makes polling more efficient, but it doesn’t fix the core problems of polling itself. Here’s how it helps:
- Multiplexing: Unlike HTTP1.1, HTTP2 lets you send multiple requests/responses over a single TCP connection. This eliminates the need for multiple concurrent connections for your polling requests (and other app requests), reducing TCP handshake overhead and connection churn.
- Header Compression: HTTP2 uses HPACK to compress request/response headers, which cuts down on the size of each polling request. For frequent requests like yours, this adds up to meaningful bandwidth savings.
- Server Push (Bonus): While not directly tied to polling, HTTP2 lets servers proactively send resources to clients when they’re needed. For your use case, this could mean pushing new message updates to clients without waiting for their next poll—though this requires reworking your flow to use persistent connections instead of periodic GETs.
But again: HTTP2 doesn’t fix the 5-second latency or unnecessary requests. It just makes the polling process cheaper and faster.
A Better Alternative: Persistent Connections (WebSocket or SSE)
If you want real-time updates without the downsides of polling, switch to a persistent connection approach. Two great options for your Node.js/Express/MongoDB stack:
1. Server-Sent Events (SSE)
SSE is simpler than WebSockets for one-way communication (server → client), which is perfect for message updates. Here’s a quick example:
Client-Side (React)
// Inside your component componentDidMount() { this.eventSource = new EventSource(`/api/messages/${this.props.session_id}`); this.eventSource.onmessage = (event) => { const newMessage = JSON.parse(event.data); // Update your state with the new message this.setState(prev => ({ messages: [...prev.messages, newMessage] })); }; } componentWillUnmount() { this.eventSource.close(); // Clean up the connection }
Server-Side (Express + MongoDB Change Streams)
app.get('/api/messages/:sessionId', async (req, res) => { // Set SSE headers res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); const sessionId = req.params.sessionId; const messagesCollection = db.collection('messages'); // Watch for new messages added to this session using MongoDB Change Streams const changeStream = messagesCollection.watch([ { $match: { 'fullDocument.session_id': sessionId, operationType: 'insert' } } ]); // Send new messages to the client as they're added changeStream.on('change', (change) => { res.write(`data: ${JSON.stringify(change.fullDocument)}\n\n`); }); // Clean up when the client disconnects req.on('close', () => { changeStream.close(); res.end(); }); });
2. WebSockets
If you need two-way communication (e.g., users sending messages and receiving updates), WebSockets are the way to go. Libraries like socket.io make this trivial with Express, and you can still use MongoDB Change Streams to trigger updates.
Final Takeaways
- Your current polling setup: Works for small apps but will scale poorly and has latency issues.
- HTTP2: Improves polling efficiency but doesn’t solve its core flaws.
- Persistent connections (SSE/WebSocket + Change Streams): The best approach for real-time messaging—low latency, minimal resource waste, and better user experience.
内容的提问来源于stack exchange,提问作者David Kamer

