Closed marekdziem closed 1 month ago
There is no idiomatic way to do this with the library, but I have seen some users implement a basic pubsub class to achieve this. Something like the following:
import {Session, Channel, createChannel} from "better-sse";
class PubSub {
private events = new Map<string, Channel>();
subscribe(session: Session, event: string): void {
if (!this.events.has(event)) {
const newChannel = createChannel();
this.events.set(event, newChannel);
// Clean up channel if no more subscribers
newChannel.on("session-deregistered", () => {
if (newChannel.sessionCount === 0) {
this.events.delete(event);
}
});
}
const channel = this.events.get(event) as Channel;
channel.register(session);
}
unsubscribe(session: Session, event: string): void {
const channel = this.events.get(event);
if (channel) {
channel.deregister(session);
}
}
publish(data: unknown, event: string): void {
const channel = this.events.get(event);
if (channel) {
channel.broadcast(data, event);
}
}
}
export {PubSub};
Essentially we create a map from an event name to a channel, and then when we subscribe a session to a given event name we register it to the corresponding channel, creating the channel if it doesn't exist already.
Channels are very lightweight and cheap to create, so this solution is still quite performant.
An example of using it would be:
const pubsub = new PubSub();
setInterval(() => {
pubsub.publish("Hello there!", "ping");
}, 1000);
app.get("/sse", async (req, res) => {
const session = await createSession(req, res);
pubsub.subscribe(session, "ping");
});
wow Many thanksd12 amazing Matthew Wid! :)
No problem 🙂
I'd like to understand how to create named channels from a unique event identifiers.
so a given channel can be dynamically created and named as the unique event name string = myEventName
how to do this? in examples you have:
const ticker = createChannel(); but how to get something like:
const eval(myEventName) = createChannel()
so I can add new sessions to the named channel based on myEventName in the path?
then broadcast to just those registered to channel myEventName?
thanks!