Fastify Server-Sent Events(SSE)

Hi friends, In this blog, I will explain Server-Sent events with an example using the Fastify library.

https://www.photopea.com/

Usually, the client(web page) initiates an HTTP call to the server for new data, and the server once receiving the request then send data to the Client.

But using the Server-Sent events server can send new data to the client at any time, by pushing messages to the web page. On the web page, this incoming message can be treated as events data.

Then you may have a question, Using the web socket also server can trigger messages to the client, then what is the difference between the Server-Sent event and WebSocket.

The main difference is the WebSocket has full-duplex communication that means, client and server can send events to each other. A good example application of using WebSocket is the chat application.

But the Server-Sent event is one way-connection, so we can not send an event from client to server. Only the server can send events to the client. Twitter updating timeline or feed are good examples of applications using Server-Sent events.

How we can implement the Server-Sent events in the Fastify application?

We can implement the Server-Sent events in two methods.

Initial set up

$ mkdir sse-fastify
$ cd sse-fastify
$ npm init -y
$ npm install fastify fastify-cors
$ touch index-1.js

Once you completed the above installation and index-1.js file creation, make the following changes in the index-1.js file.

https://carbon.now.sh/

Now we can run the project in port 3000 using the node index-1.js command.

Implement SSE

https://carbon.now.sh/

The code is the implementation of Server-Sent events.

We created a GET method called /sse . And we have eventsHandler middleware. In the eventHandler middleware, it receives request and response objects.

The next part is the header.

const headers = {
'Content-Type': 'text/event-stream',
Connection: 'keep-alive',
'Cache-Control': 'no-cache'
};
reply.raw.writeHead(200, headers);

This is an important step. ‘Connection’ should be ‘keep-alive’ then it keeps the connection open. ‘Content-Type’ should be ‘text/event-stream’. ‘Cache-Control’ is an optional one and set to ‘no-cache’.

Then set HTTP response status 200 for successful request.

In the express project, we can directly access writeHead() in the response object. But in Fastify we need to go one step deep. The writeHead() method is available in thereply.raw object.

reply.raw.write(JSON.stringify({ txt: new Date() }));

Using the above code we can send our first message to the client.

const clientId = req.id;const newClient = {
id: clientId,
response: reply
};
clients.push(newClient);

We need to store the response object for further messages to send.

In our example project, we have a setInterval function that sends the Date object to every one second. Call the listenEvent function inside the eventsHandler middleware.

Listener for connection close.

req.raw.on('close', () => {
console.log(`${clientId} Connection closed`);
clients = clients.filter((client) => client.id !== clientId);
});

The above code is a close event listener, it calls once a connection is closed and we remove that client in the client array.

In our Fastify application, we can implement SSE by fastify-sse plugin.

$ mkdir sse-fastify
$ cd sse-fastify
$ npm init -y
$ npm install fastify fastify-cors fastify-sse
$ touch index-2.js

Once you completed the above installation and index-2.js file creation, make the following changes in the index-2.js file.

https://carbon.now.sh/

The above code is a complete example of Server-Sent events using fastify-sse.

Here the important thing is we need to register the fastify-sse.

const fastify = require('fastify');
const fastifySse = require('fastify-sse');
const app = fastify();
app.register(fastifySse);

And we do not need to set a header to keep the connection open. For sending events to instead of the response.raw.write() method we can use the response.sse() method.

Using the fastify-sse we do not need to send data in stringify format, fastify-sse handle to send string format.

And it generates an id for each message. If we do not want to display the id we can pass null.

After we deployed our application with having Server-Sent event, and when we call our SSE API from the client at the time if we have an Nginx configuration we face a timeout error.

For fixing that error we need to make the following changes in the Nginx configuration.

https://carbon.now.sh/

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Edison Devadoss

Software developer / JavaScript / React / React Native / Firebase / Node.js / C Programming / Book Reader / Story Teller