The what and how of Web Push

What are web push notifications?

Native apps have had the privilege of being able to send engaging and timely content to their users since a long time. The web is closely following. Basically, you’re connected to the internet and busy with some other stuff outside your browser or surfing other websites in your browser, if you’ve allowed a website to push notifications, you will be notified with what is called a web push notification. The reason these notifications are so called is because these are ‘pushed’ by the website’s server to the client and displayed with the showNotification API. The Push API is the one responsible for sending payload across from the server to the client.

A website asking for permission from the user to push notifications displays a similar prompt and if the user agrees to be notified, the active service worker of the website subscribes to the push notifications.

What is a service worker?

A service worker is a JavaScript file that works in the background of the browser and can control the web page/ site it is associated with. It is not linked with a particular tab or page, but instead acts a proxy server for the browser by acting as a link between the website server and the browser. It handles push notifications as well as syncs APIs in the background. It keeps working even after the page or website is closed and even between browser restarts. Powerful stuff. With great power, comes great responsibility, so, service workers can only be registered on pages served over HTTPS. Since service workers are not linked to tab or web pages they don’t handle any DOM at all. However, they can communicate with open tabs and send events to them. In the future, service workers will support other things like periodic sync or geofencing (an API that lets webapps setup geographic boundaries around specific locations and then send notifications when the hosting device enters or leaves those areas.)

How do push notifications work ?

For a website to push notifications to users, it must have an active service worker. Now, for a service worker to be active : it needs to be registered first with the ServiceWorkerContainer.register() method, then downloaded immediately when a service worker controlled web page/ site is accessed, then installed only if the downloaded file is found to be new and then activated once there aren’t any loaded pages using the old service worker. After the user allows the site to push notifications, the service worker subscribes to the push service using PushManager.subscribe(). The push server generates a unique capability URL (this informs the website server about the endpoint to which notifications have to be pushed) and the encryption keys to authenticate and encrypt the data. These details are sent to the service worker which sends it to the web app server. On the web app server side, the push subscription credentials (the endpoint and encryption key sent by the service worker) are stored so that they are available when a push message needs to be sent to a push subscriber. [Capability URLs : Basically, there are 2 ways through which permission to access information is provided on the web : 1. The server asks for a correct token (like a password) from people who want to access the content OR 2. The information is present at an obscure URL and only people who have permission to access it are provided with links to it. These URLs are called capabilty URLs.]

The Push Server

The push server is the middle man, routing the payload between the web app server and the client’s service worker. Each service worker opens up a communication channel to communicate with the push service. The push service uses a globally unique UserAgent ID (UAID) to associate clients with their associated channel IDs i.e. there is only one websocket per browser and then all notifications for all service worker are routed to the same websocket using the UserAgent ID and then the browser will route the payload to the right service worker using the channel ID

Final steps

When the server has to push new content to the users, it sends an HTTP POST request to the push service with the subscription IDs of the users who are subscribed to the notifications and the encrypted payload. The request must include a TTL header (Time to Live) that limits how long the message should be queued if the user is not online. [ When data is sent over the Internet, each unit transmitted includes both header information and the actual data being sent. The header identifies the source and destination of the packet, while the actual data is referred to as the payload.]

The browser starts the service worker responsible for handling the message that was received on the UserAgent push websocket. Then the app can react to the push message being received by firing a notification through ServiceWorkerRegistration.showNotification() or by doing something else with the payload.

Here’s a diagram to help ease the confusion surrounding the whole lot of servers involved:

The Kinto Server refers to the Web App server.