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

feat(sse): add @tsed/sse package #2763

Merged
merged 1 commit into from
Aug 1, 2024
Merged

feat(sse): add @tsed/sse package #2763

merged 1 commit into from
Aug 1, 2024

Conversation

Romakita
Copy link
Collaborator

Information

Type Breaking change
Feature Yes

Server-send event let you push data to the client. It's a simple way to send data from the server to the client. The data is sent as a stream of messages, with an optional event name and id. It's a simple way to send data from the server to the client.

Installation

Before using the Socket.io, we need to install the Socket.io module.

npm install --save @tsed/sse

Then add the following configuration in your Server:

import {Configuration} from "@tsed/common";
import "@tsed/sse"; // import socketio Ts.ED module

@Configuration({
  sse: {}
})
export class Server {}

::: warning
compression middleware should be disabled for correct SSE work
:::

Enable event-stream

To enable the event-stream, you need to use the @EventStream decorator on a method of a controller.

import {Controller} from "@tsed/di";
import {Get} from "@tsed/schema";
import {EventStream, EventStreamCtx} from "@tsed/sse";

@Controller("/sse")
export class MyCtrl {
  @Get("/events")
  @EventStream()
  events(@EventStreamCtx() eventStream: EventStreamCtx) {
    let intervalId: ReturnType<typeof setInterval>;

    eventStream.on("close", () => {
      clearInterval(intervalId);
    });

    eventStream.on("end", () => {
      clearInterval(intervalId);
    });

    intervalId = setInterval(() => {
      // Ts.ED support Model serialization using json-mapper here
      eventStream.emit(new Date());
    }, 1000);
  }
}

Stream events

You can use Node.js stream like EventEmmiter to emit events from your controller to your consumer:

import {EventStream} from "@tsed/sse";
import {Controller} from "@tsed/di";
import {Get} from "@tsed/schema";

@Controller("/sse")
export class MyCtrl {
  private eventEmitter = new EventEmitter();

  $onInit() {
    setInterval(() => {
      this.eventEmitter.emit("message", new Date());
    }, 1000);
  }

  @Get("/events")
  @EventStream()
  events() {
    return this.eventEmitter;
  }
}

Observable

You can also use Observable from rxjs to emit events from your controller to your consumer:

import {EventStream} from "@tsed/sse";
import {Controller} from "@tsed/di";
import {Get} from "@tsed/schema";

@Controller("/sse")
export class MyCtrl {
  @Get("/events")
  @EventStream()
  events() {
    const observable = new Observable((observer) => {
      setInterval(() => {
        observer.next(new Date());
      }, 1000);
    });

    return observable;
  }
}

Todos

  • Tests
  • Coverage
  • Example
  • Documentation

@Romakita Romakita marked this pull request as draft July 24, 2024 17:33
@Romakita Romakita force-pushed the feat-event-stream branch 2 times, most recently from 5f960a9 to b2da9e3 Compare July 26, 2024 06:50
Copy link

Benchmarks

  • Machine: linux x64 | 4 vCPUs | 15.6GB Mem
  • Node: v18.20.4
  • Run: Fri Jul 26 2024 07:01:58 GMT+0000 (Coordinated Universal Time)
  • Method: autocannon -c 100 -d 10 -p 10 localhost:3000 (two rounds; one to warm-up, one to measure)
Version Router Requests/s Latency Throughput/Mb
koa 2.13.4 33428.0 29.36 5.96
tsed-koa 7.77.0 11368.4 87.17 9.63
express 4.19.2 10310.4 96.09 1.84
nest 8.4.3 9902.4 100.00 2.38
express-injector 4.19.2 9614.7 103.11 2.19
tsed-express 7.77.0 8521.1 116.30 1.56
express-morgan 4.19.2 5596.8 176.79 1.00
fastify-big-json 3.29.4 N/A N/A N/A
fastify-injector 3.29.4 N/A N/A N/A
fastify 3.29.4 N/A N/A N/A
nest-fastify 8.4.3 N/A N/A N/A

Explanation

The benchmark shows a performance difference between the frameworks. We note that Ts.ED is often last. In fact, Ts.ED uses features useful to a production application which reduce its performance.

For example, Ts.ED initializes a sandbox (async_hook) for each request in order to work in an isolated context if necessary.
It also initializes the elements necessary for monitoring requests in a log manager.

All this at a necessary cost that reflects the reality of a production application ;)

Copy link

Benchmarks

  • Machine: linux x64 | 4 vCPUs | 15.6GB Mem
  • Node: v18.20.4
  • Run: Mon Jul 29 2024 07:49:04 GMT+0000 (Coordinated Universal Time)
  • Method: autocannon -c 100 -d 10 -p 10 localhost:3000 (two rounds; one to warm-up, one to measure)
Version Router Requests/s Latency Throughput/Mb
koa 2.13.4 33391.3 29.41 5.95
tsed-koa 7.78.0 11834.5 83.71 10.02
express 4.19.2 10064.0 98.53 1.79
nest 8.4.3 9815.8 100.83 2.36
express-injector 4.19.2 9440.2 105.04 2.15
tsed-express 7.78.0 8828.4 112.29 1.62
express-morgan 4.19.2 5563.1 177.86 0.99
fastify-big-json 3.29.4 N/A N/A N/A
fastify-injector 3.29.4 N/A N/A N/A
fastify 3.29.4 N/A N/A N/A
nest-fastify 8.4.3 N/A N/A N/A

Explanation

The benchmark shows a performance difference between the frameworks. We note that Ts.ED is often last. In fact, Ts.ED uses features useful to a production application which reduce its performance.

For example, Ts.ED initializes a sandbox (async_hook) for each request in order to work in an isolated context if necessary.
It also initializes the elements necessary for monitoring requests in a log manager.

All this at a necessary cost that reflects the reality of a production application ;)

Copy link

github-actions bot commented Aug 1, 2024

Benchmarks

  • Machine: linux x64 | 4 vCPUs | 15.6GB Mem
  • Node: v18.20.4
  • Run: Thu Aug 01 2024 07:02:23 GMT+0000 (Coordinated Universal Time)
  • Method: autocannon -c 100 -d 10 -p 10 localhost:3000 (two rounds; one to warm-up, one to measure)
Version Router Requests/s Latency Throughput/Mb
koa 2.13.4 31250.9 31.47 5.57
tsed-koa 7.78.1 11323.3 87.53 9.59
express 4.19.2 10276.2 96.49 1.83
nest 8.4.3 9568.5 103.51 2.30
express-injector 4.19.2 9042.7 109.34 2.06
tsed-express 7.78.1 8171.0 121.14 1.50
express-morgan 4.19.2 5199.9 190.10 0.93
fastify-big-json 3.29.4 N/A N/A N/A
fastify-injector 3.29.4 N/A N/A N/A
fastify 3.29.4 N/A N/A N/A
nest-fastify 8.4.3 N/A N/A N/A

Explanation

The benchmark shows a performance difference between the frameworks. We note that Ts.ED is often last. In fact, Ts.ED uses features useful to a production application which reduce its performance.

For example, Ts.ED initializes a sandbox (async_hook) for each request in order to work in an isolated context if necessary.
It also initializes the elements necessary for monitoring requests in a log manager.

All this at a necessary cost that reflects the reality of a production application ;)

Copy link

github-actions bot commented Aug 1, 2024

Benchmarks

  • Machine: linux x64 | 4 vCPUs | 15.6GB Mem
  • Node: v18.20.4
  • Run: Thu Aug 01 2024 07:23:23 GMT+0000 (Coordinated Universal Time)
  • Method: autocannon -c 100 -d 10 -p 10 localhost:3000 (two rounds; one to warm-up, one to measure)
Version Router Requests/s Latency Throughput/Mb
koa 2.13.4 32483.6 30.26 5.79
tsed-koa 7.78.1 11844.0 83.53 10.03
express 4.19.2 10122.4 97.75 1.81
nest 8.4.3 9400.2 105.41 2.26
express-injector 4.19.2 9377.0 105.69 2.14
tsed-express 7.78.1 8428.2 117.69 1.54
express-morgan 4.19.2 5568.2 177.77 0.99
fastify-big-json 3.29.4 N/A N/A N/A
fastify-injector 3.29.4 N/A N/A N/A
fastify 3.29.4 N/A N/A N/A
nest-fastify 8.4.3 N/A N/A N/A

Explanation

The benchmark shows a performance difference between the frameworks. We note that Ts.ED is often last. In fact, Ts.ED uses features useful to a production application which reduce its performance.

For example, Ts.ED initializes a sandbox (async_hook) for each request in order to work in an isolated context if necessary.
It also initializes the elements necessary for monitoring requests in a log manager.

All this at a necessary cost that reflects the reality of a production application ;)

@Romakita
Copy link
Collaborator Author

Romakita commented Aug 1, 2024

@IvaDey This PR can be review and add officially the sse support to Ts.ED ;)

@Romakita Romakita marked this pull request as ready for review August 1, 2024 07:35
@Romakita Romakita merged commit c38eea0 into production Aug 1, 2024
15 checks passed
@Romakita Romakita deleted the feat-event-stream branch August 1, 2024 17:36
@Romakita
Copy link
Collaborator Author

Romakita commented Aug 1, 2024

🎉 This PR is included in version 7.79.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Successfully merging this pull request may close these issues.

1 participant