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

No way to hook into outbound acknowledgements with middlewares #4882

Open
NyaStone opened this issue Nov 28, 2023 · 0 comments
Open

No way to hook into outbound acknowledgements with middlewares #4882

NyaStone opened this issue Nov 28, 2023 · 0 comments
Labels
enhancement New feature or request

Comments

@NyaStone
Copy link

NyaStone commented Nov 28, 2023

I've been working on some middleware for data validation and infering the event types using a zod schema.
When looking for how to handle acknowledgements through my middleware I found a few unexpected behavors of catch-all listener.

It is possible to add some logic before acknowledging a client's request.

socket.use(packet: [string, ...any[]], next:(err?: Error) => void) {
    console.log(packet);
    // [ 'eventWithAck', [Function (anonymous)] ]
    next();
};

socket.on('eventWithAck', (ack: () => void) => {
    ack();
});

client.emit('eventWithAck', () => {
    console.log('done');
});

Here we can get access to the callback that is responding to the client, and we can wrap it with our own logic to be run right before the acknowledgement is sent.

socket.use(packet: [string, ...any[]], next:(err?: Error) => void) {
    if (packet.length && typeof packet[packet.length-1] === 'function') {
        const callback: (...args: any[]) => void = packet[packet.length-1];
        packet[packet.length-1] = (...args: any[]) => {
            console.log(args);
            // [ 'some data' ]
            callback(...args);
        }
    }
    next();
};

socket.on('eventWithAck', (ack: (data: string) => void) => {
    ack('some data');
});

client.emit('eventWithAck', () => {
    console.log('done');
});

The issue is that this is only achievable to check acknledgement that we send out, not the incomming acknowlegements data packets.
I had expected to achieve a similar logic using the catch-all listeners.
The documentation on the Socket.io website stated that catch all listeners don't trigger upon recieving/sending acknoledgements, but i hoped being able to get a reference to the acknowledgement callback before the emit is being sent, so i could wrap it with my logic. Wrapping the acknowledgement callback there allows me to also have context of the initial emited event (before it's sent) for tha added logic.
However when I tried i quickly noticed that the acknowledgement callback gets stripped away from the data packet and sent to the acknowledgement listeners before the catch-all listeners get called.
Second issue with this proposition is that I don't know if the spread arguments would pass the callback by reference so it can be wrapped.

While writing this I noticed that the documentation in VS code of catch all listeners does warn me about the callback being stripped.

The solution proposed here #4649 seems like migration hell because of potential collisions when suddenly triggering the listeners for new reasons.

Changing the definition of the catch-all listeners to have the callback being passed as reference would be a real migration pain too. Even tho it would be a good way of having the context of the event that originates the acknowledgement.

Best option I could see would be a method to add middleware support for outgoing requests among these lines :

public useOutgoing(eventPacket: any[], next: (err?: Error) => void) {
    // the packet being passed as reference allows us to manipulate it and wrap the acknowledgement callback with validation logic
}

Currently working on a fork to demonstrate. (just have to add some more test cases)

@NyaStone NyaStone added the enhancement New feature or request label Nov 28, 2023
@NyaStone NyaStone changed the title Unexpected behavior from catch-all listeners. No way to hook into outbound acknowledgements with middlewares Nov 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant