nodejs / help

:sparkles: Need help with Node.js? File an Issue here. :rocket:
1.47k stars 282 forks source link

How does `agent.createConnection` handle WebSockets when `maxSockets=1`? #4176

Closed mStirner closed 4 months ago

mStirner commented 1 year ago

Details

I try to understand the anatomy of a http request/live cycle better. I think for most of the developers this is not necessary, but i want to go down the rabbit hole.

When i have a custom http agent create, and set maxSockets=1 & keepAlive=true, how does the agent handle this situation? In my minimal reproducable example, for each Websocket connection a new tcp socket is created, event when maxSockets set to 1.

Where/how does the agent knew he has to create a new connection because the first one is still needed? I would expect that maxSockets tell the agent, "no matter what, you only create one tcp socket". In combination with WebSockets this seems dumb, and i wonder even more how this is handled by the agent.

Node.js version

v16.20.0

Example code

client.js

const { Agent } = require("http")
const { createConnection } = require("net");
const WebSocket = require("ws");

const agent = new Agent({
    maxSockets: 1,
    keepAlive: true
});

agent.createConnection = (options) => {

    let { host, port } = options;

    console.log("Create connection", host, port);

    let socket = createConnection(options);
    return socket;

};

const ws1 = new WebSocket("ws://127.0.0.1:8080", {
    agent
});

const ws2 = new WebSocket("ws://127.0.0.1:8080", {
    agent
});

[ws1, ws2].forEach((ws) => {

    ws.on("open", () => {
        console.log("WebSocket opend: %s", ws.url);
    });

    ws.on("close", () => {
        console.log("WebSocket closed: %s", ws.url);
    });

});

server.js

const { Server } = require("ws");

const wss = new Server({
    port: 8080
});

wss.on("connection", (ws) => {

    console.log("Client connected");

    ws.on("close", () => {
        console.log("Client disconnected");
    });

});

wss.on("listening", () => {
    console.log("Server listening")
});

Operating system

Ubuntu 18.04.6 LTS

Scope

no clue

Module and version

Not applicable.

preveen-stack commented 1 year ago

Guess max connection will be applicable only to http connections and once the connection is upgraded to websockets it will no longer be effective

mStirner commented 1 year ago

and once the connection is upgraded to websockets it will no longer be effective

And how does the underlaying http module signal/notify that to the agent?

preveen-stack commented 1 year ago

The spec details this quite extensively at https://datatracker.ietf.org/doc/html/rfc6455 As for implementation, folks at https://github.com/websockets/ws can probably better articulate

github-actions[bot] commented 5 months ago

It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.

github-actions[bot] commented 4 months ago

It seems there has been no activity on this issue for a while, and it is being closed. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.