Server-Sent Events (SSE) is a technology based on HTTP. On the client-side, it provides an API called EventSource (part of the HTML5 standard) that allows us to connect to the server and receive updates from it.
Let's create a simple chat system
First, we are gonna create a new nodeJS project
Let's name it sse-server
Now, let's initiate npm to install some dependencies
We are gonna add express
, body-parser
and cors
In index.ts
- Configure the middleware
import express from 'express'; import bodyParser from 'body-parser'; import cors from 'cors'; const app = express(); app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false }));
- Specify the PORT
const PORT = 3000;
- Declare and initialise the required variables
// Contains the connected clients info let clients: any[] = []; // Contains the messages of the network const messages: any[] = [];
- Create a endpoint where the clients will subscribe to events
app.get('/messages', (request: any, response: any) => { const headers: any = { 'Content-Type': 'text/event-stream', Connection: 'keep-alive', 'Cache-Control': 'no-cache' }; response.writeHead(200, headers); const data: string = `data: ${JSON.stringify(messages)}\n\n`; response.write(data); const clientId = (request.query.id ?? 'guest') + '_' + Date.now(); const newClient: any = { id: clientId, response }; clients.push(newClient); request.on('close', () => { console.log(`${clientId} Connection closed`); clients = clients.filter((client: any) => client.id !== clientId); }); });
- A function to notify whenever a new message arrives in the network
const notifyMessageToAllUsers = (userIdWithoutUnderscore: string) => { clients .filter( (client: any) => String(client.id).split('_')[0] != userIdWithoutUnderscore ) .forEach((client: any) => { client.response.write(`data: ${JSON.stringify(messages)}\n\n`); }); };
- Finally an endpoint to push messages to the network
app.post('/message', (request, response) => { if ( request.query.id && request.body && request.body.message && String(request.body.message).trim() ) { messages.push({ user_id: request.query.id, message: request.body.message.trim() }); notifyMessageToAllUsers(String(request.query.id)); response.send({ status: 200, error: 'Message Sent Succesfully' }); } else { response.send({ status: 400, error: 'Bad Request' }); } });
- let's start the server
app.listen(PORT, () => { console.log(`Server is listening at http://localhost:${PORT}`); });
$ npm start
Server console
$ Server is listening at http://localhost:3000
For pushing a message to the network
$ curl --location --request POST 'http://localhost:3000/message?id=1234' \ --header 'Content-Type: application/json' \ --data-raw '{ "message": "Hi" }'
To listen to the messages
curl --location --request GET 'http://localhost:3000/messages' \ --header 'Accept: text/event-stream'
After subscribing to the endpoint, we should be able to see the message that was pushed earlier
$ data: [{"user_id":"1234","message":"Hi"}]
Conclusion
SSE is very powerful in terms of receiving events from the server to achieve real-time behaviour in the client. But it can get very expensive if it's not implemented efficiently.
Thanks for Reading!
Thanks for reading, I hope you enjoyed it!
Top comments (0)