lolo32 / fastify-sse

Provide Server-Sent Events to Fastify
20 stars 16 forks source link

fastify-sse

Build Status Coverage Status Known Vulnerabilities

Easily send Server-Send-Events with Fastify.

This is based on github.com/mtharrison/susie

Install

npm install --save fastify-sse

Usage

Add it to you project with register and you are done!

You can now configure a new route, and call the new reply.sse() to send Events to browser.

When you have finished sending event, you could send an empty message, or if using stream and end of stream, an end event will be fired just before closing the connection. You could work with it browser side to prevent automatic reconnection.

// Register the plugin
fastify.register(require("fastify-sse"), (err) => {
    if (err) {
      throw err;
    }
});

// Define a new route in hapijs notation
fastify.route({
  method: "GET",
  url: "/sse-hapi",
  handler: (request, reply) => {
    let index;
    const options = {};

    // Send the first data
    reply.sse("sample data", options);

    // Send a new data every seconds for 10 seconds then close
    const interval = setInterval(() => {
      reply.sse({event: "test", data: index});
      if (!(index % 10)) {
        reply.sse();
        clearInterval(interval);
      }
    }, 1000);
  }
});

// Define a new route in express notation
fastify.get("/sse-express",(request, reply) => {
    let index;
    const options = {};

    // Send the first data
    reply.sse("sample data", options);

    // Send a new data every seconds for 10 seconds then close
    const interval = setInterval(() => {
      reply.sse({event: "test", data: index});
      if (!(index % 10)) {
        reply.sse();
        clearInterval(interval);
      }
    }, 1000);
  });

The options are used only for the first call, subsequent ignore it.

You could specify:

Options

idGenerator

It must be a function that will be called with the event in parameter, and must return a string that will be the id of the SSE, or it could be null if no id is needed.

Using a function:

reply.sse("message", {
  idGenerator: (event) => {
    // Retrieve the event name using the key myIdentifiant or use the timestamp if not exists …
    return event.myIdentifiant || (new Date()).getTime();
  }
});

It will transmit:

id: 1504624133267

data: message

Do not display id, so pass null:

reply.sse("message", {idGenerator: null});

It will transmit:

data: message

event

It could be:

reply.sse({myEventName: "myEvent", hello: "world"}, {
  event: (event) => {
    // Retrieve the event name using the key myEventName …
    const name = event.myEventName;
    // … delete it from the object …
    delete event.myEventName;
    // then return the name
    return name;
  }
});

It will transmit:

id: 1

event: MyEvent

data: {"hello":"world"}