This is a one-way communication that is made with the server by making a single persistent connection. Initially, the client makes a connection with the server and waits for the trigger of the event by the server and the server triggers the events on the client by sending some messages to the client.
Now, we will learn to get notified from the server through server-sent events (in short SSE)
We have to use two different perspectives for this task, which are:
- Client Side: To start a connection
- Server Side: To accept the client requests
On the client side, we create an HTML page and with EventSource class we make an asynchronous request to the server.
EventSource class opens a persistent connection with the server and also provides a method to listen to the server events
We need to create an instance of this class, like:
Syntax:
var sse = new EventSource("url");
where,
- sse is the EventSource object
The method used to listen for the server messages is “message“.
Syntax:
sse.onmessage = (event)=>{ ... }
On the Server side, I am using express and nodejs to listen for the client requests, but you can prefer your favorite server-side language.
Syntax:
var express = require("express"); var app = express(); app.get('/events', async function(req, res) { res.set({ 'Cache-Control': 'no-cache', 'Content-Type': 'text/event-stream', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin':'*' }); res.flushHeaders(); res.write('hi'); } app.listen(3000);
In the above code, we are listening at port 3000 and at some URL-PATH
Make sure you make the connection persistent using the header ‘Connection’: ‘keep-alive’ and make the response type as event-stream ‘Content-Type’: ‘text/event-stream’
Browser implements CORS so specify ‘Access-Control-Allow-Origin’:’*’
using res to send notifications to the client.
Example: In the below example we will connect at “http://localhost:3000/events” and print the server message on the console tab. On the server side, we will listen to the “/events” URL using the express GET method.
In the server-side code, we create a function run that registers a listener function, and by using res object we send messages to the EventSource instance.
The server sends the message, which is the value of the counter that counts every one second, iteratively.
- Client-Side code:
HTML
< html > < body > < script type = "text/javascript" > const source = new EventSource('http://localhost:3000/events'); source.addEventListener('message', message => { console.log('Got', message); }); </ script > </ body > </ html > |
Output:
- Server-Side code:
Javascript
'use strict' ; const express = require( 'express' ); run(). catch (err => console.log(err)); async function run() { const app = express(); app.get( '/events' , async function (req, res) { console.log( 'Got /events' ); res.set({ 'Cache-Control' : 'no-cache' , 'Content-Type' : 'text/event-stream' , 'Connection' : 'keep-alive' , 'Access-Control-Allow-Origin' : '*' }); res.flushHeaders(); // Tell the client to retry every 10 seconds // if connectivity is lost res.write( 'retry: 1000 \n\n' ); let count = 0; while ( true ) { await new Promise(resolve => setTimeout(resolve, 1000)); console.log( 'Emit' , ++count); // Emit an SSE that contains the current // 'count' as a string res.write(`data: ${count}\n\n`); } }); await app.listen(3000); console.log( 'Listening on port 3000' ); } |
Output: The output represents the emission of the data which is the counter that counts every second