rexxars / sse-channel

Server-Sent Events "channel" where all messages are broadcasted to all connected clients, history is maintained automatically and server attempts to keep clients alive by sending "keep-alive" packets automatically.
MIT License
111 stars 11 forks source link

Feature suggestion: Send filters #25

Open joepie91 opened 5 years ago

joepie91 commented 5 years ago

So I've been thinking over the problem described in #19 for a bit, having run into a variant of it myself (though with more complex channel logic), and I think that a reasonable general-purpose solution for handling channels would be 'send filters'.

An example of a simple 'chat channel' scenario, with such an API:

sseChannel.send(message, (req, res, message) => {
    let user = users.get(req.session.userId);

    return user.channels.has(message.channel);
});

(In this example, assume users to be a Map, and user.channels to be a Set.)

Essentially, the send filter could be specified instead of an array of clients, and it would be called for each combination of message and candidate client.

The major benefit of this compared to the current clients argument (which takes an array of response objects) is that this approach doesn't need to bypass the history, because the filter function can also be applied to past messages upon reconnection, and the filter itself can use persistent data (like session data) to determine eligibility for receiving a message.

Right now, when you specify an array of clients, the message doesn't get added to the history and therefore doesn't get sent after any reconnects; this makes sense because a 'client' from the perspective of sse-channel is just a response object, and a reconnected client would be a different response object with no way to tie it to the previous client.

The feature suggested here would also allow arbitrarily complex logic for determining whether a particular client should receive a particular message, without needing further changes in sse-channel itself in the future.


Update: The filter function could even be specified during initialization of the channel, rather than for each individual message. That would reduce flexibility, but also reduce overhead and implementation complexity.