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)