Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a Server Sent Event Service using Node.js #11

Open
chen86860 opened this issue Jan 2, 2022 · 0 comments
Open

Create a Server Sent Event Service using Node.js #11

chen86860 opened this issue Jan 2, 2022 · 0 comments

Comments

@chen86860
Copy link
Owner

SSE (server-sent events) example using Node.js

SSE is a easy way to commutate with the client side in a single direction. it has loss cost and efficiency way compared to other protocols like Socket or polling query.

Here is a minium checklist to create a SSE service:

Server Side

  1. response three HTTP headers that tell the client that the response is a SSE stream:

    • Connection: keep-alive
    • Content-Type: text/event-stream
    • Cache-Control: no-cache
  2. response data with data , event and id attributes

  3. That's all

Client Side

  1. create a EventSource object

  2. addEventListener to the EventSource object

  3. That's all


There is a simple example to show how to create a SSE service using Node.js.

Installation

Install dependencies before running example.

$ yarn

Start

$ yarn start // start client
$ yarn run server // start server

After run command above, you can open http://localhost:1234 see the result in the browser.

Server

The server is a simple Node.js application that listens on port 3000. I create a Server Sent Event while sends data to the client interval in one second. Here is the core core of the server.

ctx.set({
  // necessary HTTP Headers for server sent events
  Connection: "keep-alive",
  "Content-Type": "text/event-stream",
  "Cache-Control": "no-cache",

  // CORS settings
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Credentials": "true",
});

const pipe = new stream.PassThrough();
// normalize message without event name specified
pipe.write(`id: ${Math.random()}\ndata: hello from steam\n\n`);

const interval = setInterval(() => {
  // normalize message with event name(eg:currentTime) specified
  pipe.write(`id: ${Math.random()}\nevent: currentTime\ndata: ${new Date().toUTCString()}\n\n`);
}, 1000);

ctx.body = pipe;

// clear interval and destroy stream object while client disconnect
ctx.res.on("close", () => {
  clearInterval(interval);
  pipe.destroy();
});

Client

In the client side, it's easy to create a event source to listen on the server. the EventSource object return a readable stream which you can addEventListener by open, message and error event. Also, you can create custom event listeners by addEventListener method. see example below:

const source = new EventSource(API, {
  withCredentials: true,
});

source.addEventListener("open", (e: Event) => {
  console.log("event source is open");
});

// event name not specified, message is default
source.addEventListener("message", (e: MessageEvent) => {
  console.log("'message' event received:", e.data);
});

// event name(eg:currentTime) specified
source.addEventListener("currentTime", (e: any) => {
  console.log("'currentTime' event received:", e.data);
});

source.addEventListener("error", (e: Event) => {
  console.error("event source error", e);
  source.close();
});

Related repository: sse-example

Enjoy Hacking!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant