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

Web server refuses connections although max socket connections not exceeded (IDFGH-8004) #9514

Closed
mbratch opened this issue Aug 7, 2022 · 5 comments
Assignees
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@mbratch
Copy link

mbratch commented Aug 7, 2022

I am using ESP-IDF v4.4.1 on an ESP32-Pico Kit v4.1.

My application has a REST API server which has been working well. I wanted to add a WebSocket interface, using the ESP32 as a WebSocket server, so I added a handler for it, in addition to my REST API path handlers.

    const httpd_uri_t httpdUri = {
        .uri = "/ws",
        .method = HTTP_GET,
        .handler = wsStart,
        .user_ctx = nullptr,
        .is_websocket = true
    };
    
    httpd_register_uri_handler(_server, &httpdUri);

Here's the handler function:

esp_err_t WebServer::wsStart(httpd_req_t *req)
{
    auto& status = Status::instance();
    auto& webServer = WebServer::instance();

    status.logf(Status::logInfo, "Starting websocket, handle = %d, fd = %d", req->handle, httpd_req_to_sockfd(req));

    webServer.wsSetHandle(req->handle);

    esp_err_t rc = webServer.wsSetFd(httpd_req_to_sockfd(req));

    if (rc == ESP_FAIL)
        status.log(Status::logError, "Too many websocket handles allocated");

    return rc;
}

In the javascript client, when the page is loaded, I open the WebSocket:

	let webSocket = new WebSocket(`ws://${location.host}/ws`);

	webSocket.onopen = function() {
		console.log('Websocket to BD-OTP open')
	}

	webSocket.onmessage = function(event) {
	    const output = JSON.parse(event.data)
            // Update DOM element based upon data
	}
	
	webSocket.onclose = function() {
		console.log('Websocket to BD-OTP closed')
		webSocket = null
	}

	webSocket.onerror = function(event) {
		console.log(`WebSocket ERROR: ${JSON.stringify(event, null, 4)}`);
	}

The WebSocket is basically working, but here's the problem: if I reload the page a number of times, the server soon stops responding. I have my maximum sockets set to 16 in my SDK config (which limits the actual number to 13 sockets in the code). But I do not have 13 sockets open, at least not based upon what I'm seeing. The following log is generated using handlers for the open_fn and close_fn events for the server:

I (25521) BD-OTB: Open socket hd = 1073549484, fd = 51
I (25541) BD-OTB: Open socket hd = 1073549484, fd = 52
I (25631) BD-OTB: Open socket hd = 1073549484, fd = 53
I (25726) BD-OTB: Open socket hd = 1073549484, fd = 54
I (25736) BD-OTB: Starting websocket, handle = 1073549484, fd = 54
I (37206) BD-OTB: Close socket hd = 1073549484, fd = 54
I (37386) BD-OTB: Open socket hd = 1073549484, fd = 55
I (37401) BD-OTB: Starting websocket, handle = 1073549484, fd = 55
I (47751) BD-OTB: Close socket hd = 1073549484, fd = 55
I (47976) BD-OTB: Open socket hd = 1073549484, fd = 56
I (47991) BD-OTB: Starting websocket, handle = 1073549484, fd = 56
I (50201) BD-OTB: Close socket hd = 1073549484, fd = 56
I (50371) BD-OTB: Open socket hd = 1073549484, fd = 57
I (50381) BD-OTB: Starting websocket, handle = 1073549484, fd = 57
I (50386) BD-OTB: Open socket hd = 1073549484, fd = 58
I (51231) BD-OTB: Close socket hd = 1073549484, fd = 57
I (51411) BD-OTB: Open socket hd = 1073549484, fd = 59
I (51421) BD-OTB: Starting websocket, handle = 1073549484, fd = 59
I (52051) BD-OTB: Close socket hd = 1073549484, fd = 59
I (52231) BD-OTB: Open socket hd = 1073549484, fd = 60
I (52241) BD-OTB: Starting websocket, handle = 1073549484, fd = 60
I (57896) BD-OTB: Close socket hd = 1073549484, fd = 60
I (58091) BD-OTB: Open socket hd = 1073549484, fd = 61
I (58101) BD-OTB: Starting websocket, handle = 1073549484, fd = 61
I (58811) BD-OTB: Close socket hd = 1073549484, fd = 61
I (58986) BD-OTB: Open socket hd = 1073549484, fd = 62
I (58996) BD-OTB: Starting websocket, handle = 1073549484, fd = 62
I (59626) BD-OTB: Close socket hd = 1073549484, fd = 62
I (59826) BD-OTB: Open socket hd = 1073549484, fd = 63
I (59836) BD-OTB: Starting websocket, handle = 1073549484, fd = 63
I (60451) BD-OTB: Close socket hd = 1073549484, fd = 63
W (60641) httpd: httpd_accept_conn: error in accept (23)
W (60641) httpd: httpd_server: error accepting new connection
W (61361) httpd: httpd_accept_conn: error in accept (23)
W (61361) httpd: httpd_server: error accepting new connection
W (62261) httpd: httpd_accept_conn: error in accept (23)
W (62266) httpd: httpd_server: error accepting new connection

From this log, when the client page is initially loaded, several sockets are opened, including the websocket. Each subsequent reload of the page generally closes the prior WebSocket and opens one new one in its place. I don't see a net gain in open sockets here. Nonetheless, after a few reloads, the ESP32 server stops responding and won't accept any more connections. This problem gets worst and happens much sooner if I add support for more WebSocket clients. In order to remedy this issue, I have to reboot the ESP32. Waiting for sockets to timeout and close does not resolve the issue.

@espressif-bot espressif-bot added the Status: Opened Issue is new label Aug 7, 2022
@github-actions github-actions bot changed the title Web server refuses connections although max socket connections not exceeded Web server refuses connections although max socket connections not exceeded (IDFGH-8004) Aug 7, 2022
@ESP-YJM
Copy link
Collaborator

ESP-YJM commented Aug 8, 2022

Hi @mbratch , i think you can find the solution in #9395.

@espressif-bot espressif-bot assigned ESP-YJM and unassigned mahavirj Aug 8, 2022
@mbratch
Copy link
Author

mbratch commented Aug 8, 2022

@ESP-YJM thank you! I tried that and it appears to be working properly now after some brief testing.

@chipweinberger
Copy link
Contributor

chipweinberger commented Aug 11, 2022

@ESP-YJM, IMO httpd_config_t.so_linger = false should be added & the default behavior =)

@ESP-YJM
Copy link
Collaborator

ESP-YJM commented Aug 12, 2022

@chipweinberger Yes, that's a good idea. Add so_linger config can make sense.

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels Aug 29, 2022
@espressif-bot espressif-bot assigned hmalpani and unassigned ESP-YJM Sep 12, 2022
@espressif-bot espressif-bot added Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Resolution: Done Issue is done internally and removed Status: In Progress Work is in progress Resolution: NA Issue resolution is unavailable labels Sep 22, 2022
@chipweinberger
Copy link
Contributor

chipweinberger commented Sep 23, 2022

Great to see that merged, @ESP-YJM!

Is there a reason we don't care about the return value of setsockop? Please see my comment: #9395 (comment)

espressif-bot pushed a commit that referenced this issue Sep 30, 2022
espressif-bot pushed a commit that referenced this issue Oct 13, 2022
loganfin pushed a commit to Lumenaries/esp_http_server that referenced this issue Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

6 participants