Server-Sent Events
is a client-server communication technique with a one-way communication flow. Yes, as it implies the server will sent the data to the client while the client initially establishes a connection using Event Source and sits idle.
I'm familiar with communication techniques like Short polling, Long polling, and Web Sockets and I implemented them at certain stages in my development journey.
There came a situation where I have to find and use the right technique to solve the problem at hand, and this article is all about why and how I did it.
Before moving here's a quick overview of each of the technique:
Short Polling:
The client repeatedly requests data from the server at fixed intervals. Simple but inefficient as it creates unnecessary network traffic when there's no new data.Long Polling:
The client makes a request, and the server holds the connection open until it has new data to send. Less wasteful than short polling but can still be resource-intensive on the server.Web Sockets:
Creates a persistent, bi-directional connection between client and server. Great for real-time applications where both sides need to communicate freely, but can be overkill for simpler use cases.Server Sent Events:
Establishes a one-way connection from server to client. The server can push data whenever it's ready while maintaining a single persistent connection. Lightweight and built into standard HTTP.
Here's why I had to use Server-Sent Events in my case:
Client will make an API call to the Server consisting of multiple user's data from the dashboard, which the server will process one by one and send the results back one by one.
Initially I thought of using the Web Sockets for the above problem. But upon considering the nature of the problem, design architecture and the use-case it makes a clear sense to use Server-Sent Events.
Here's why:
Simpler Implementation:
SSE requires minimal setup compared to Web Sockets. The client-side code is surprisingly straightforward.One-way Communication Flow:
In my case, data only needed to flow from server to client. The client requests the process to start, and then just listens for updates. No need for the overhead of bi-directional communication.Standard HTTP:
No special protocols or ports needed, making it easier to work with existing infrastructure and firewalls.
Implementation
Here's a gist of how I implemented it:
Server-side (Node.js with Express):
app.get('/api/process-data', (req, res) => {
// Set SSE headers
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
// Get users from the request
const users = req.query.users.split(',');
// Process each user and send results as they complete
users.forEach((user, index) => {
// Simulate processing time
setTimeout(() => {
const data = JSON.stringify({
user,
result: `Processed data for ${user}`,
progress: ((index + 1) / users.length) * 100
});
// Send the event
res.write(`data: ${data}\n\n`);
// If last user, end the response
if (index === users.length - 1) {
res.write(`data: ${JSON.stringify({ done: true })}\n\n`);
}
}, index * 1000); // Process each user with a delay
});
});
Client-side:
function processUserData(users) {
// Create the EventSource
const eventSource = new EventSource(`/api/process-data?users=${users.join(',')}`);
// Handle incoming messages
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.done) {
console.log('Processing complete!');
eventSource.close();
return;
}
console.log(`User: ${data.user}, Result: ${data.result}`);
updateProgressBar(data.progress);
};
// Error handling
eventSource.onerror = (error) => {
console.error('SSE error:', error);
eventSource.close();
};
}
function updateProgressBar(progress) {
const progressBar = document.querySelector('.progress-bar');
progressBar.style.width = `${progress}%`;
progressBar.textContent = `${Math.round(progress)}%`;
}
Advantages I Discovered
Bandwidth Efficiency:
Unlike Web Sockets which maintain a constant connection, SSE only sends data when there's something to send.Easy Debugging:
Since it's just HTTP, I could test and debug using standard tools like browser dev tools or Postman.Scalability:
For my use case of processing user data sequentially, SSE scaled well without the connection management complexity of Web Sockets.
Progressive Updates: Users see results as they become available, rather than waiting for all processing to complete.
Limitations to Keep in Mind:
It's not all sunshine and rainbows though. SSE does have some limitations:
Connection Limits:
Browsers typically limit the number of concurrent SSE connections (usually 6 per domain).One-way Communication Only:
If you need the client to send data back frequently, SSE isn't the right choice.IE Support:
If you need to support Internet Explorer, you'll need a polyfill.
Conclusion
Sometimes the simplest solution is the best one. While Web Sockets get all the glory in real-time applications, Server-Sent Events provided exactly what I needed with minimal overhead and complexity.
For use cases where you need server-to-client updates without the complexity of Web Sockets, give SSE a try. You might find it's the solution you didn't know you needed.
Have you used SSE in your projects? I'd love to hear about your experiences in the comments below!
Top comments (0)