MatthewWid / better-sse

⬆ Dead simple, dependency-less, spec-compliant server-sent events implementation for Node, written in TypeScript.
https://matthewwid.github.io/better-sse/
MIT License
559 stars 14 forks source link

How to destroy a channel? :P #36

Closed santiblanko closed 2 years ago

santiblanko commented 2 years ago

Awesome library!

MatthewWid commented 2 years ago

Hi there. Could you clarify what you mean by "destroy a channel"?

If you would like to stop all sessions from receiving events from a channel, you should deregister every registered session from the channel:

channel.activeSessions.forEach(channel.deregister);

And then prevent future sessions from being registered with the channel.

Otherwise, you should simply remove any references to channel and it will be garbage collected.

If you have an example of what you are trying to achieve that would be more helpful.

Thanks for submitting an issue!

santiblanko commented 2 years ago

Check for example

  const session = await createSession(req, res);
  const name = req.query.channel || "";
  const channel = createChannel();
  channel.register(session);
  channels.push({
    name: name,
    channel: channel
  });
  channel.broadcast(req.query.channel, "channel-created");
});

I wan't to destroyChannel when the user disconnect. Because I wan't a custom channel on every connection for privacy and performance.

MatthewWid commented 2 years ago

Is channels an array of channels and you want to remove it when the session disconnects? In that case, you can listen for the disconnect event and then remove the created channel from the channels list. Here's a full code sample:

import express from "express";
import {createSession, createChannel} from "better-sse";

const app = express();

const channels = [];

app.get("/sse", async (req, res) => {
        const session = await createSession(req, res);

        const name = req.query.channel;

        // Error if no name is given
        if (!name) {
                return res.sendStatus(400);
        }

        const channel = createChannel().register(session);

        channels.push({name, channel});

        channel.broadcast(name, "channel-created");

        // Could also use `channel.once("session-deregisted", ...)`
        session.once("disconnected", () => {
                // Find where the channel is in the channels list
                const index = channels.findIndex((channel) => channel.name === name);

                // If the channel is not found do nothing
                if (index === -1) {
                        return;
                }

                // Remove the channel from the list
                channels.splice(index, 1);
        });
});

app.listen(8080);

I haven't tested this, you might have to tweak a few things. Also keep in mind if you add more than one session to a channel here and a single session disconnects the entire channel will still be removed from the list - modify as you wish.

Note that if you simply want to push an event to a single session you can skip using channels altogether and just push an event to the session directly:

session.push("Hello there!", "greeting");

This is more performant and "private" as there's no chance of you accidentally registering multiple sessions to the same channel.

If I'm still misunderstanding your use-case please let me know.

santiblanko commented 2 years ago

The session works perfect!! :)