26 Nov Long polling: the poor man's push
Having a server push data to the client is one of the coolest things you can do for your web application. I'm sure we've all came across this issue before: when writing a chat app, you do something like `(() => setInterval(getMessages, 1000))()`. The problem is, you only get new messages every 1000ms. No matter what interval you choose, it's either going to be too long or too short. This is what "polling" is - the client periodically pings the server for new data.
Today, pushing data can be accomplished using [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket). Your client can listen for updates simply by adding an event listener: `new WebSocket('ws://host:8080').addEventListener('message', ...);`. Many people use [Express](https://expressjs.com/) with a NodeJS backend for their WebSocket adventures. This is fairly easy to setup since all you need is some VPS somewhere. However, hosting is not free. I've used [Vultr](https://www.vultr.com/pricing/) before and it's quite nice, but it's still a monthly expense on top of the shared Apache hosting I currently buy. How can we achieve push without shiny new tech like NodeJS and Express? Enter long polling.
Long polling is when we make the server keep a connection alive until new data is sent to the client. In your backend, keep a [busy-wait](https://wikipedia.org/wiki/Busy_waiting) until new messages are queried from the database.
```
while(!fetchNewMessages()) {}
```
This keeps the XHR alive. In your client, send an XHR to the backend that calls itself recursively after resolving.
```
function getMessages() {
fetch('chat/messages').then(updateUI).then(getMessages);
}
```
This is probably not the best solution, but I've used it before in a school project many years ago. There's something magical about achieving something that _looks_ like push without WebSockets, but I highly recommend using WebSockets for modern projects :)
Comments
Cool!