Not closing sockets in examples
Created by: TechnicalLee
Hardware: Arduino Uno WiFi Rev 2 Software: Arduino IDE 1.8.13 with WiFiNINA library 1.8.2
I was using your OpenWeatherMap example from your book, but I ran into a No socket available error after repeated http errors. This is the part of the code where you check if the header is okay:
// Check status code
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
// should be "HTTP/1.0 200 OK"
if (memcmp(status + 9, "200 OK", 6) != 0) {
Serial.print(F("Unexpected HTTP status"));
Serial.println(status);
return;
}
About 10% of the time when fetching weather I get Unexpected HTTP status
from the above. After that happened 10 times, I would get the No socket available
error and no further communication is possible. I also noticed the amount of available memory decreased by 66 bytes after every error. After looking through the WiFiNINA library, I found there is a 10 socket limit which matches the number of failed attempts before the no sockets error. I conclude that sockets are being left open when you are returning from errors, so that's why they eventually run out. The fix is simple, you just need to add a client.stop()
to close the socket before each return from any error:
// Check status code
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
// should be "HTTP/1.0 200 OK"
if (memcmp(status + 9, "200 OK", 6) != 0) {
Serial.print(F("Unexpected HTTP status"));
Serial.println(status);
client.stop(); //<---Add here
return;
}
// Deserialize the response
DynamicJsonDocument doc(8192);
DeserializationError err =
deserializeJson(doc, client, DeserializationOption::Filter(filter));
if (err) {
Serial.print(F("deserializeJson() returned "));
Serial.println(err.c_str());
client.stop(); //<---Add here
return;
}
Those are the two instances in the OpenWeatherMap example, it looks like this would also affect the Adafruitio example in your book, and the JsonServer and JsonHttpClient examples in this library.
This is probably moving into another issue, but when I get those http errors it's always because the header is blank, so it seems like it's having trouble keeping up with the stream or interruptions sometimes. Every so often I also get a deserializeJson() returned IncompleteInput
even though the response header was okay. You mentioned this could be some kind of stream race problem back in #969 (closed), but I was curious if you had any fix or update with your StreamUtils to add to the examples? Right now I'm just living with the 10% error rate.