In my application the user can turn off and on the WiFi and, as consequence, the ESPAsyncWebServer. Here my relevant code:
AsyncWebServer _server;
void WebApp::Begin()
{
MDNS.begin(APP_NAME);
MDNS.addService("http", "tcp", 80);
_server.on("/api/datetime", HTTP_GET, [this](AsyncWebServerRequest *request)
{
// do something
}
// several other callbacks
// enable captive portal only if we are in hotspot
if (_network.Mode() == Network::Modes::Hotspot) _server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);
DefaultHeaders::Instance().addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
DefaultHeaders::Instance().addHeader("Pragma", "no-cache");
DefaultHeaders::Instance().addHeader("Expires", "0");
_server.begin();
}
void WebApp::End()
{
_server.end();
_isRunning = false;
}
I call these functions here:
// in my main loop if station is enabled
if (WiFi.isConnected())
{
Serial.print(F("[NET] Connected to: "));
Serial.println(WiFi.SSID());
Serial.print(F("[NET] Local IP: "));
Serial.println(WiFi.localIP());
Serial.print(F("[NET] RSSI: "));
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
_provisioning.SetNtp();
webapp.Begin();
_mode = Modes::Station;
}
or when set the hotspot mode:
Network::setHotspot()
{
turnOffWifi();
_mode = _lastMode = Modes::Hotspot;
IPAddress local_ip(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
WiFi.mode(WIFI_MODE_AP);
WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_ip, gateway, subnet);
WiFi.softAPsetHostname(APP_NAME);
esp_wifi_set_ps(WIFI_PS_NONE);
Serial.printf("[NET] Start DNS: %s\n",_dns.start(53, "*", WiFi.softAPIP()) ? "success" : "failed");
Serial.print(ssid);
Serial.print(F(" "));
Serial.println(password);
Serial.print(F("[NET] Local IP: "));
Serial.println(WiFi.softAPIP());
webapp.Begin();
}
void Network::turnOffWifi()
{
Serial.println("[NET] Turning off Wifi");
if (webapp.IsRunning()) webapp.End();
if (sntp_enabled) sntp_stop();
WiFi.mode(WIFI_OFF);
while (static_cast<int8_t>(WiFi.status()) > WL_IDLE_STATUS)
{
Serial.println(WiFi.status());
yield();
delay(500);
}
Serial.println("[NET] Done");
}
After 1-2 turn off/on cycle, the ESPAsyncWebServer and DNS services do not start anymore:
[258253][E][AsyncTCP.cpp:1487] begin(): bind error: -8
I found this issue and it seems to be no solution other than to avoid calling the end()
function. But in my application I do need to stop the webserver when I switch among WiFi modes (offline/station/hotspot) and when I start a different webserver for provisioning.
Is there a reliable way to stop and restart ESPAsyncWebServer?