gilmaimon / ArduinoWebsockets

A library for writing modern websockets applications with Arduino (ESP8266 and ESP32)
GNU General Public License v3.0
477 stars 96 forks source link

[E][WiFiClient.cpp:309] setOption(): fail on fd -1, errno: 9, "Bad file number" #57

Open friedemannm opened 4 years ago

friedemannm commented 4 years ago

Describe the bug Strange warning when connecting to a websocket server: [E][WiFiClient.cpp:309] setOption(): fail on fd -1, errno: 9, "Bad file number"

To Reproduce Just connect to a websocket server as shown in the examples.

Expected behavior This warning is unexpected...

Code Should be able to reproduce with the given examples.

Additional context ESP32, framework-arduinoespressif32 2.10004.191002 (1.0.4)

gilmaimon commented 4 years ago

Is this a warning only or error? Is there anything wrong with the connection itself? What sketch are you running?

gilmaimon commented 4 years ago

I'm running this example sketch:

using namespace websockets;

WebsocketsClient client;
void setup() {
    Serial.begin(115200);
    // Connect to wifi
    WiFi.begin(ssid, password);

    // Wait some time to connect to wifi
    for(int i = 0; i < 10 && WiFi.status() != WL_CONNECTED; i++) {
        Serial.print(".");
        delay(1000);
    }

    // Check if connected to wifi
    if(WiFi.status() != WL_CONNECTED) {
        Serial.println("No Wifi!, But lest keep going");
    }

    Serial.println("Connected to Wifi, Connecting to server.");
    // try to connect to Websockets server
    bool connected = client.connect("ws://192.168.14.114:1234");
    if(connected) {
        Serial.println("Connecetd!");
        client.send("Hello Server");
    } else {
        Serial.println("Not Connected!");
    }

    // run callback when messages are received
    client.onMessage([&](WebsocketsMessage message){
        Serial.print("Got Message: ");
        Serial.println(message.data());
    });
}

void loop() {
    // let the websockets client check for incoming messages
    if(client.available()) {
        client.poll();
    }
    delay(500);
}

with verbose debug logs, but I see nothing except:

[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 0 - WIFI_READY
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
.[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 7 - STA_GOT_IP
[D][WiFiGeneric.cpp:381] _eventCallback(): STA IP: 192.168.14.25, MASK: 255.255.255.0, GW: 192.168.14.1
Connected to Wifi, Connecting to server.
Connecetd!
Got Message: hello

Are you connecting to a wss server?

Thanks for opening the issue, Gil.

gilmaimon commented 4 years ago

No response, no issue 👍

kosso commented 4 years ago

Hi, Oddly enough I found this (closed) issue while looking up the same error.

I don't know if this is related, but since I use a non-default secure port number, I found I had to use the full connection string to connect via wss:// eg:

const char *websockets_connection_string = "wss://ws.mydomain.uk:444/";
...
while (!client.connect(websockets_connection_string)) {
    delay(500);
    Serial.print(".");
}
..etc. 

And when I connect, I also see : [E][WiFiClient.cpp:309] setOption(): fail on fd -1, errno: 9, "Bad file number"

I also tried adding : client.setFragmentsPolicy(FragmentsPolicy_Notify); before connect.

I note that it doesn't appear to actually break anything, but something is clearly not being configured correctly, maybe?

gilmaimon commented 4 years ago

Great, I'll re-open.

You should not call connect multiple times on the same object. You should reset the object or do something like:

while(true) {
   WebsocketsClient temp;
   if (temp.connect(....)) {
      client = temp;
      break;
   }
}

Or do anything else such that connect will only be called once per client.

If you can adjust your code and manage to reproduce, I'll also try to re-produce this myself.

Gil.

friedemannm commented 4 years ago

Sorry for no reply for so long time. I have problems with unreliable websocket connections (timeouts from time to time). But I don't think its related to this warning.

I'm also not using the wss default port. I connect to Port 444 with a self signed certificate and the appropriate SHA Hash.

kosso commented 4 years ago

Hi,

I have adjusted my code to use a temporary object for connection similar to your example. (I also had to set my certificate and callbacks on the temp client object before connecting.)

But I am still seeing the same error. [E][WiFiClient.cpp:309] setOption(): fail on fd -1, errno: 9, "Bad file number"

(I am also using port 444 on a LetsEncrypt certificate on my remote websocket server running a NodeJS script. Web-based clients have no problems or errors connecting via JS)

gilmaimon commented 4 years ago

Hi @friedemannm , is it possible that you get timeouts after long durations of inactivity? I know many server implementations are disconnecting clients after some time of inactivity, one way to solve this is by pinging the server (client.ping).

Regarding the warning, it seems like it is caused because I'm calling setNoDelay on the WiFiClients created by the library. The code used for standard clients and secured clients is the same (a template), but it seems like for SecureWiFiClient that option is not supported.

It seems like this warning has no negative effect other than the annoying message, I don't think this is worth the cost of "fixing".

Gil.

whiteboxsolutions commented 4 years ago

I'm also getting this issue when trying to connect to the websocket.org's echo server (wss://echo.websocket.org)

EDIT to add more info:

Using an ESP32 based "Heltec Wifi Kit 32"

Code is copied straight from example, with the following change:

const char* websockets_server = "wss://echo.websocket.org"; //server address and port

gb-123-git commented 2 years ago

Its giving this error as it cannot reference this function from the original class.