socket.io-prometheus-metrics icon indicating copy to clipboard operation
socket.io-prometheus-metrics copied to clipboard

Feature: Binding emit for room messages

Open KonkretneKosteczki opened this issue 5 years ago • 1 comments

Out of all emit possibilities only socket based ones are supported

// sending to the client
socket.emit('hello', 'can you hear me?', 1, 2, 'abc');
// sending to all clients except sender
socket.broadcast.emit('broadcast', 'hello friends!');
// sending to all clients in 'game' room except sender
socket.to('game').emit('nice game', "let's play a game");
// sending to all clients in 'game1' and/or in 'game2' room, except sender
socket.to('game1').to('game2').emit('nice game', "let's play a game (too)");

Please add support to io:

// sending to all clients in 'game' room, including sender
io.in('game').emit('big-announcement', 'the game will start soon');
// sending to all clients in namespace 'myNamespace', including sender
io.of('myNamespace').emit('bigger-announcement', 'the tournament will start soon');
// sending to a specific room in a specific namespace, including sender
io.of('myNamespace').to('room').emit('event', 'message');
// sending to individual socketid (private message)
io.to(socketId).emit('hey', 'I just met you');

It can be done in the exact same way as the socket ones. If i was to write an more generic function for hooking onto emits I would get something like:

private emitHook(
    originalEmit: (event: string, ...data: unknown[]) => boolean,
    emitter: NodeJS.EventEmitter,
    labels: prom.LabelValues<string>
) {
    return (event: string, ...data: unknown[]) => {
        if (this.blacklisted_events.has(event))
            return originalEmit.apply(emitter, [event, ...data]);

        const labelsWEvent = {event: event, ...labels};
        this.metrics.bytesTransmitted.inc(labelsWEvent, SocketIOMetrics.dataToBytes(data));
        this.metrics.eventsSentTotal.inc(labelsWEvent);

        return originalEmit.apply(emitter, [event, ...data]);
    };
}

Which can be used to hook onto socket events

        // Hook into emit (outgoing event)
        socket.emit = this.emitHook(socket.emit, socket, labels);

And io events

    // Hook into emit (outgoing event)
    server.emit = this.emitHook(server.emit, server, labels);

KonkretneKosteczki avatar Nov 12 '20 12:11 KonkretneKosteczki

Thanks for the suggestion. This will be a good candidate for a feature for version 2 of this project. It can be found on the v2 branch but it is very much a work in progress.

Feel free to contribute if you like!

naueramant avatar Nov 18 '20 19:11 naueramant