Changing data: polling, SSE, WebSocket, and webhook
Objectives
By the end of the lesson, you can tell the four refresh patterns (polling, SSE, WebSocket, webhook) apart by direction, initiator, and connection persistence, and you can choose among them for a task with justification.
Why is it not enough to query once?
HTTP is request–response based: the client asks, the server answers. This is fine if the data changes rarely, but the number of free places, live results, or the state of a shared edit can change continuously. If the server cannot speak up by itself, the client's interface soon becomes stale. The following patterns all fill this gap, but in different directions, at different costs.
On the course page the student sees that three places are left. Meanwhile others can enrol too. None of the solutions replaces the server's final check: the "there is still room" display is momentary information, not a guaranteed reservation.
flowchart TB
P[Polling: repeated client request] --> C[Fresh data for the client]
S[SSE: server event stream] --> C
W[WebSocket: two-way connection] --> C
H[Webhook: server notifies another server] --> R[Another system]
Polling: a new request from time to time
With polling the client asks for the data again at set intervals. On the trial server this is a simple HTTP request:
It is simple because it uses the existing API. Its drawback: it asks even when nothing has changed, and a change becomes visible only at the next fetch. It is acceptable for rarely changing data; with per-second refreshing and many clients it is already costly. The polling frequency is the joint result of the user's need, the server load, and the speed at which the data changes. On error the client must not send the same thing again immediately and without limit (the server can defend itself with a 429 response, 2.4).
Server-Sent Events: from the server to the client
Server-Sent Events (SSE) is an HTTP-based event stream: through the open connection the server can send messages later as well. According to MDN the server must send a Content-Type: text/event-stream header, the messages consist of field: value lines, and a blank line closes one. In the browser the EventSource API receives it, and if the connection breaks the browser reconnects by itself.
The trial server sends three events at half-second intervals (curl -N, so that it does not buffer the output):
Every event has an identifier (id), a name (event), and data (data). SSE is one-way: from the server to the client. If the client initiates an operation, it does so with a separate HTTP request. According to MDN, over HTTP/1.1 browsers allow about 6 SSE connections per browser and domain (over HTTP/2 this limit does not apply). The advantage of SSE is the simpler, one-way model, not that it is always "more real-time".
WebSocket: two-way messages
WebSocket enables persistent, two-way message exchange between the client and the server (according to MDN, the client does not have to poll for the answer). It can be justified if both parties often initiate: in shared editing, in an interactive game. The connection starts with an HTTP request in which the client asks for a protocol switch (Upgrade). According to RFC 6455 the request contains Upgrade: websocket, Connection: Upgrade, a Sec-WebSocket-Key key, and Sec-WebSocket-Version: 13. The server answers 101 Switching Protocols, and computes the value of Sec-WebSocket-Accept from the key (it appends a fixed GUID to the key, then applies SHA-1 and base64).
The received Sec-WebSocket-Accept value equals the example of the RFC, so the server computed it correctly. (The example shows only the handshake; we did not implement the framing of the actual two-way messages.)
Two-way communication means more state handling: the server has to manage the open connections, the client the disconnection, reconnection, and the missed changes. For a rarely updated course list, WebSocket is overkill. The technology is determined by the need, not by how the words "real-time" sound. MDN also notes that the WebSocket API has no backpressure, so quickly arriving messages can exhaust memory or the processor.
Webhook: a system notifies a system
With a webhook, when an event occurs a service sends an HTTP request to a pre-specified address of another service. For example, the enrolment system notifies the statistics system about a new enrolment. The receiving party must check that the notification really comes from the expected sender; a common method is a signature: the sender and the receiver hold a shared secret, and the sender computes an HMAC (Hash-based Message Authentication Code) signature from the body with it, and sends it in a header.
The trial receiver checks the signature (SHA-256 HMAC, X-Alairas header):
The signature comes from the body and the shared secret; a forger cannot produce it. The receiver must also handle repeated or failed delivery (the sender may retry), so the receiving operation must be idempotent (2.3).
How do we choose?
Pattern
Direction
Connection
When is it good?
Polling
client → server asks
new for each request
rarely changing data, simplicity
SSE
server → client
persistent, one-way
live status, news feed
WebSocket
two-way
persistent
shared editing, games, frequent two-way messages
Webhook
server → server
one request per event
notification between systems
Worked example: the number of free places in Kurzuspont
Need
Choice
Reason
The page should refresh the number of free places every 30 seconds
polling
simple, the existing API is enough
When enrolment opens, the number should drop at once on everyone's screen
SSE
the server sends the change, the client sends nothing
Enrolments should notify the university statistics system
webhook
server–server event
A shared study-group editor for notes
WebSocket
two-way, frequent messages
A "free: 0" display is in no case a reservation: at the moment of enrolment the server must check the place separately (2.4: 409).
Common misconceptions
Statement
Clarification
"Real-time refreshing always needs WebSocket."
Polling or SSE can also meet the need.
"In SSE both parties send events on the same channel."
SSE is a stream going from the server to the client.
"A webhook is a notification to the browser."
Typically a service sends an HTTP request to another service.
"The displayed free place is a sure reservation."
The server must check separately at enrolment.
"A webhook is trustworthy without a signature."
Anyone can send a request to the address; the signature verifies the sender.
In brief
Polling is repeated asking, SSE is a one-way server→client stream, WebSocket is a persistent two-way channel, a webhook is an event request between services.
A WebSocket starts with an HTTP request and switches protocol with a 101 Switching Protocols response.
A webhook receiver must verify the sender (signature) and handle repetition.
The choice depends on direction, frequency, and cost.
A displayed state is not a reservation.
Review questions
How does polling differ from SSE?
What is the role of 101 Switching Protocols in the WebSocket handshake?
Why must the webhook receiver check the signature?
Which pattern would you choose for a rarely updated news list, and which for shared editing?
Changing data: polling, SSE, WebSocket, and webhook
Objectives
By the end of the lesson, you can tell the four refresh patterns (polling, SSE, WebSocket, webhook) apart by direction, initiator, and connection persistence, and you can choose among them for a task with justification.
Why is it not enough to query once?
HTTP is request–response based: the client asks, the server answers. This is fine if the data changes rarely, but the number of free places, live results, or the state of a shared edit can change continuously. If the server cannot speak up by itself, the client's interface soon becomes stale. The following patterns all fill this gap, but in different directions, at different costs.
On the course page the student sees that three places are left. Meanwhile others can enrol too. None of the solutions replaces the server's final check: the "there is still room" display is momentary information, not a guaranteed reservation.
flowchart TB P[Polling: repeated client request] --> C[Fresh data for the client] S[SSE: server event stream] --> C W[WebSocket: two-way connection] --> C H[Webhook: server notifies another server] --> R[Another system]Polling: a new request from time to time
With polling the client asks for the data again at set intervals. On the trial server this is a simple HTTP request:
It is simple because it uses the existing API. Its drawback: it asks even when nothing has changed, and a change becomes visible only at the next fetch. It is acceptable for rarely changing data; with per-second refreshing and many clients it is already costly. The polling frequency is the joint result of the user's need, the server load, and the speed at which the data changes. On error the client must not send the same thing again immediately and without limit (the server can defend itself with a 429 response, 2.4).
Server-Sent Events: from the server to the client
Server-Sent Events (SSE) is an HTTP-based event stream: through the open connection the server can send messages later as well. According to MDN the server must send a
Content-Type: text/event-streamheader, the messages consist offield: valuelines, and a blank line closes one. In the browser theEventSourceAPI receives it, and if the connection breaks the browser reconnects by itself.The trial server sends three events at half-second intervals (
curl -N, so that it does not buffer the output):Every event has an identifier (
id), a name (event), and data (data). SSE is one-way: from the server to the client. If the client initiates an operation, it does so with a separate HTTP request. According to MDN, over HTTP/1.1 browsers allow about 6 SSE connections per browser and domain (over HTTP/2 this limit does not apply). The advantage of SSE is the simpler, one-way model, not that it is always "more real-time".WebSocket: two-way messages
WebSocket enables persistent, two-way message exchange between the client and the server (according to MDN, the client does not have to poll for the answer). It can be justified if both parties often initiate: in shared editing, in an interactive game. The connection starts with an HTTP request in which the client asks for a protocol switch (Upgrade). According to RFC 6455 the request contains
Upgrade: websocket,Connection: Upgrade, aSec-WebSocket-Keykey, andSec-WebSocket-Version: 13. The server answers101 Switching Protocols, and computes the value ofSec-WebSocket-Acceptfrom the key (it appends a fixed GUID to the key, then applies SHA-1 and base64).The trial server with the example key of the RFC:
The received
Sec-WebSocket-Acceptvalue equals the example of the RFC, so the server computed it correctly. (The example shows only the handshake; we did not implement the framing of the actual two-way messages.)Two-way communication means more state handling: the server has to manage the open connections, the client the disconnection, reconnection, and the missed changes. For a rarely updated course list, WebSocket is overkill. The technology is determined by the need, not by how the words "real-time" sound. MDN also notes that the
WebSocketAPI has no backpressure, so quickly arriving messages can exhaust memory or the processor.Webhook: a system notifies a system
With a webhook, when an event occurs a service sends an HTTP request to a pre-specified address of another service. For example, the enrolment system notifies the statistics system about a new enrolment. The receiving party must check that the notification really comes from the expected sender; a common method is a signature: the sender and the receiver hold a shared secret, and the sender computes an HMAC (Hash-based Message Authentication Code) signature from the body with it, and sends it in a header.
The trial receiver checks the signature (SHA-256 HMAC,
X-Alairasheader):The signature comes from the body and the shared secret; a forger cannot produce it. The receiver must also handle repeated or failed delivery (the sender may retry), so the receiving operation must be idempotent (2.3).
How do we choose?
Worked example: the number of free places in Kurzuspont
A "free: 0" display is in no case a reservation: at the moment of enrolment the server must check the place separately (2.4:
409).Common misconceptions
In brief
101 Switching Protocolsresponse.Review questions
101 Switching Protocolsin the WebSocket handshake?Learning resources