Long Polling
With polling, the server sends a response to each request right away. Most of the time, the response is “nothing new”.
Instead, when there is nothing new, the server can keep the request and not send a response yet.
Keeping the request
Team 4’s room is room 12, and the newest message on Marcus’s screen is 61842. Marcus’s client sends the same request as before:
sequenceDiagram
participant P as Priya's client
participant S as Server
participant M as Marcus's client
M->>S: GET /rooms/12/messages?after=61842
Note over S: nothing new, keeps the request
The room has nothing after 61842, so the server keeps the request and does not send a response yet. Marcus’s client is still waiting for its response. A browser waits for a slow page in the same way.
Then Priya posts the link to the design doc:
sequenceDiagram
participant P as Priya's client
participant S as Server
participant M as Marcus's client
M->>S: GET /rooms/12/messages?after=61842
Note over S: nothing new, keeps the request
P->>S: POST /rooms/12/messages
S-->>P: 201, message 61843
S-->>M: 200, message 61843
Now the server has something to send. It sends Priya’s message, which it saved as 61843, as the response to the request it kept. Marcus sees the message right away.
The next request
The server has sent its response. It has no request from Marcus’s client anymore. If Priya posts again now, the server has no request to respond to. The server cannot send anything until the client sends a request.
So as soon as Marcus’s client gets a response, it sends a new request. That request carries after=61843, and the server keeps it too:
sequenceDiagram
participant P as Priya's client
participant S as Server
participant M as Marcus's client
M->>S: GET /rooms/12/messages?after=61842
Note over S: nothing new, keeps the request
P->>S: POST /rooms/12/messages
S-->>P: 201, message 61843
S-->>M: 200, message 61843
M->>S: GET /rooms/12/messages?after=61843
Note over S: nothing new, keeps the request
This way, the server almost always has a request from Marcus’s client to respond to.
The server keeps each request until it has something to send, and the client sends a new request after every response. This is called long polling. Each of those requests is a long poll.
Long polling in history
In 2006, people started to call this technique Comet: the server keeps HTTP requests so that it can send new data to a browser. When Facebook launched its chat for about 70 million users in 2008, it delivered messages by long polling.
Here is the client’s code. It is a loop: send the request, show any messages, and send the next request right away.
async function longPoll(roomId) {
let after = newestMessageIdOnScreen();
while (true) {
const messages = await getMessages(roomId, after); // waits until the server answers
for (const message of messages) {
showOnScreen(message);
after = message.id;
}
// Back to the top: send the next request right away
}
}
This is a sketch, close to pseudocode. getMessages sends GET /rooms/{room_id}/messages?after=... and waits for the response. newestMessageIdOnScreen and showOnScreen stand for the code that reads and updates the page. A real client also handles a failed request. For example, it waits a moment before it sends the next one.