Is it possible to pause/suspend (don’t accept(2) on the socket) a Node.js server?

1.1k views Asked by At

Goal: To have a Node.js server where only one connection is active at a time.

I can temporarily remove the connection event listener on the server, or only set it up once in the first place by calling once instead of on, but then any connection that gets made while there is no connection event listener seems to get lost. From strace, I can see that Node is still accept(2)ing on the socket. Is it possible to get it to not do that, so that the kernel will instead queue up all incoming request until the server is ready to accept them again (or the backlog configured in listen(2) is exceeded)?

Example code that doesn’t work as I want it to:

#!/usr/bin/node
const net = require("net");
const server = net.createServer();
function onConnection(socket) {
    socket.on("close", () => server.once("connection", onConnection));
    let count = 0;
    socket.on("data", (buffer) => {
        count += buffer.length;
        if (count >= 16) {
            socket.end();
        }
        console.log("read " + count + " bytes total on this connection");
    });
}
server.once("connection", onConnection);
server.listen(8080);
  1. Connect to localhost, port 8080, with the agent of your choice (nc, socat, telnet, …).
  2. Send less than 16 bytes, and witness the server logging to the terminal.
  3. Without killing the first agent, connect a second time in another terminal. Try to send any number of bytes – the server will not log anything.
  4. Send more bytes on the first connection, so that the total number of bytes sent there exceeds 16. The server will close this connection (and again log this to the console).
  5. Send yet more bytes on the second connection. Nothing will happen.

I would like the second connection to block until the first one is over, and then to be handled normally. Is this possible?

1

There are 1 answers

0
lossleader On BEST ANSWER

.. so that the kernel will instead queue up all incoming request until the server is ready to accept them again (or the backlog configured in listen(2) is exceeded)? ... I would like the second connection to block until the first one is over, and then to be handled normally. Is this possible?

Unfortunately, it is not possible without catching the connection events that are sent and managing the accepted connections in your application rather than with the OS backlog. node calls libuv with an OnConnection callback that will try to accept all connections and make them available in the JS context.