- Published on
Method of Real-Time Communication
TL;DR
- Websocket: 2 ways communication (chat, gaming, collaboration,..)
- SSE: one-way communication (server -> client), ideal for notification, live feed,...
- Polling: easiest to implementation but inefficient at scale.
Problem
You're understand the HTTP request and wanna building a realtime feature like chat, notification, live,... but the HTTP request restrict you to do that. The real-time communication can help to solve these problem.
But there're a lots of method to implement
Should I use Websocket, SSE or Polling to my business?
Choosing a wrong mechanism lead to:
- redundance workload to solve the simple things
- inefficient cost
- slow your app
Intuition
Thinking communication are:
- Polling: messaging someone repeatedly to ask
anything new? - SSE: messaging someone
let me know if you have anything new?and they will message to you back whenever they have a new things. - Websocket: Staying on a live call, you're video call to someone and you will know whenever they have a new things and they also know your new things.
Solution Overview
There're 3 common approaches:
| Method | Direction | Realtime | Complexity | Use Cases |
|---|---|---|---|---|
| Polling | Client -> Server | ❌ | Simple | Simple dashboard, delayed notification,.. |
| SSE | Server -> Client | ✅ | Medium | Notification, live update,... |
| Websocket | Both directions | ✅ | Hard | Streaming, chats, game, collaboration, ... |
Deep Dive
Polling
The client repeatedly sends requests by wrap them into the setInterval function:
// this function run every 3s from Frontend
setInterval(async () => {
const res = await fetch('/api/messages')
const data = await res.json()
updateUI(data)
}, 3000)
SSE - Server-Sent Events (SSE)
The server send event to the client whenever they have an updated:
const eventSource = new EventSource('/events')
eventSource.onmessage = (event) => {
console.log(event.data)
}
Websocket
Websocket is the two ways connection from server and client. It has a persistent connection from server and client, whenever they have updates, the update will be sent to others.
Server connection
Understand this like the SSE. Sometime you need to send the update for the concurrent user like hunt for discount, have a new feeds, real-time dashboard (delivery tracking, revenue,...),...
Thinking that you need to update to their client about newest information instead of waiting for the new refresh.
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 3000 })
wss.on('connection', (ws) => {
console.log('Client connected')
// send to client
ws.send('Hello from server')
// receive from client
ws.on('message', (message) => {
console.log('Received:', message.toString())
})
// ... adding more listening message
// close connection trigger
ws.on('close', () => {
console.log('Client disconnected')
})
})
Client connection
Proactive checking a new data. user request when they have something to update or exchange with server or partner in the system.
User A send a message to user B and that's important message. It would be instantly send to user B without waiting to refresh (user B don't know when user A message to him). At this case, server proactively send message to user A.
const ws = new WebSocket('ws://localhost:3000')
ws.onopen = () => {
console.log('Connected to server')
}
// listen from Server
ws.onmessage = (event) => {
console.log('Server says:', event.data)
}
// ... adding more listening message here
// close connection trigger
ws.onclose = () => {
console.log('Disconnected')
}
// send to server
function sendMessage() {
const input = document.getElementById('msg')
ws.send(input.value)
input.value = ''
}
Trade-offs
Polling
Pros
- Easy to implement
Cons
- Wastes resources (many empty requests)
- Not truly real-time
- DDoS (accidentally by multiple user at the time)
- Need handle caching on Server
SSE
Pros:
- Efficient for update from server to client
- Reduce spam request from client (compare with Polling)
- Good performance
Cons:
- One way only
- Limited browser support compared to HTTP
Websocket
Pros
- Real-time absolutely
- Fast connection, send and receive data
- 2-way connection
- Excellent performance (in two-way direction)
Cons
- Costly for both server and client to keep connecting
- High complexity
When to use
Polling using for small app and priority feature more than performance.
SSE suitable for medium app, building notification, live feed update, ...
Websocket suitable for chat app, streaming, gaming, collaboration app,...
Anti-pattern
- Avoid using Websocket for small app, notification (SSE is more suitable)
- Using combination of Polling and SSE for chatting, streaming, gaming instead of Websocket.
- Using Websocket + SSE for chat and notification. This lead unnecessary (SSE) because Websocket can using for both Chat and Notification. (except you have specific cases that prefer SSE than Websocket - in most cases, Websocket can handle both).
Conclusion
- Using Polling to reduce complexity of small app
- Using SSE for notification, real-time feature (not the keys feature)
- Using Websocket for chat, streaming