Web server on both interfaces in WIFI_AP_STA mode?

I'm on an ESP32-DevKitC-VIE kit (WROVER-IE module). I configure the wifi as WIFI_AP_STA and spin up a webserver on port 80.

It connects to the local network fine and serves webpages over that, but when I connect to the device AP directly, the webserver doesn't respond (which is reasonable of course, as no other configuration has been done.)

I've seen a few threads where people are struggling with this (many on ESP8266) but I can't find any answers for my device/code. Looking at the APIs there doesn't seem to be any provision for specifying the interface to use.

Any ideas? Ideally I would have one webserver respond to both interfaces, but if I have to spin up a separate webserver I think that would be acceptable as well.

Should I be using a different library to achieve this?

Current code (summary):


#include <Arduino.h>
#include <WiFi.h>
#include "esp_wifi.h"

const char* wifi_network_ssid     = "localssid";
const char* wifi_network_password = "password";
const char *soft_ap_ssid          = "ap_netname";
const char *soft_ap_password      = NULL; // NULL for no password
const int   channel        = 10;    // WiFi Channel number between 1 and 13
const bool  hide_SSID      = false; // To disable SSID broadcast -> SSID will not appear in a basic WiFi scan
const int   max_connection = 2;     // Maximum simultaneous connected clients on the AP

WiFiServer espServer(80);

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

    WiFi.mode(WIFI_AP_STA);

    Serial.println("\n[*] Creating ESP32 AP");
    WiFi.softAP(soft_ap_ssid, soft_ap_password, channel, hide_SSID, max_connection);
    Serial.print("[+] AP Created with IP Gateway ");
    Serial.println(WiFi.softAPIP());

    IPAddress ip(192,168,3,23);   
    IPAddress gateway(192,168,3,1);   
    IPAddress subnet(255,255,255,0);   
    WiFi.config(ip, gateway, subnet);

    WiFi.begin(wifi_network_ssid, wifi_network_password);
    Serial.println("\n[*] Connecting to WiFi Network");

    while(WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(100);
    }

    Serial.print("\n[+] Connected to the WiFi network with local IP : ");
    Serial.println(WiFi.localIP());

    Serial.println("Starting webserver");
    espServer.begin();
    Serial.println("Started webserver");
}

void loop()
{
  WiFiClient client = espServer.available();
  if (client) handleWebClient(client);
}

WebServer(IPAddress addr, int port = 80);

the IP address defines the network interface to use

Thanks Juraj! -- was just coming back to post that I found that, but it didn't seem to work? If I do:

espServer = WiFiServer(IPAddress(192,168,3,23), 80);
espServer.begin();

...it works (this is the STA IP). But if instead I do:

espServer = WiFiServer(IPAddress(192,168,4,1), 80);
espServer.begin();

...and then I connect to the AP and try http://192.168.4.1, it does not work.

Should I be using WebServer instead of WiFiServer? What is the difference? I found a little bit online but it didn't quite explain the pros/cons... EDIT: I see, WiFiServer doesn't speak http, WebServer does. But does it matter which I use in terms of using the AP vs STA?

WebServer has WiFiServer inside and passes the IP address to it.

Thanks again -- based on your advice and this example code, I tried to get this working, but I'm still having trouble.

Below is my current code -- do you see anything obvious that I am doing wrong?

I can connect on the STA interface via http://esp32.local and http://esp32.local:8080 and I get the expected responses ("dual" vs "STA" server responses.) But when I connect to the soft AP, I get nothing on either http://esp32.local or http://esp32.local:8080... or if I use the IP (e.g. http://192.168.4.1:8080).

Terminal output is as expected:

[+] Static IP forced: 192.168.3.23

[*] Connecting to WiFi Network
.......
[+] Connected to the WiFi network with local IP : 192.168.3.23

[*] Creating ESP32 AP
[+] AP Created with IP Gateway 192.168.4.1
Soft AP SSID: "esp32", IP address: 192.168.4.1
MDNS started.
Starting webserver
Started webservers
#include <Arduino.h>
#include <WiFi.h>
#include "WebServer.h"
#include <ESPmDNS.h>

const char* wifi_network_ssid     = "mynetwork";
const char* wifi_network_password = "mypassword";
const char *soft_ap_ssid          = "apnetname";
const char *soft_ap_password      = NULL; // NULL for no password
const int   channel        = 10;    // WiFi Channel number between 1 and 13
const bool  hide_SSID      = false; // To disable SSID broadcast -> SSID will not appear in a basic WiFi scan
const int   max_connection = 2;     // Maximum simultaneous connected clients on the AP

WebServer *webserver, *APwebserver, *STAwebserver;

void handleWebRequest()
{
  webserver->send(200, "text/plain", "this is the dual webserver");
}

void handleAPWebRequest()
{
  APwebserver->send(200, "text/plain", "this is the AP webserver");
}

void handleSTAWebRequest()
{
  STAwebserver->send(200, "text/plain", "this is the STA webserver");
}

void handleNotFound(WebServer *server)
{
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server->uri();
  message += "\nMethod: ";
  message += (server->method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server->args();
  message += "\n";
  for (uint8_t i = 0; i < server->args(); i++) {
    message += " " + server->argName(i) + ": " + server->arg(i) + "\n";
  }
  server->send(404, "text/plain", message);
}

void handleDualNotFound()
{
  handleNotFound(webserver);
}
void handleNotFoundAP()
{
  handleNotFound(APwebserver);
}
void handleNotFoundSTA()
{
  handleNotFound(STAwebserver);
}

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

    WiFi.mode(WIFI_STA);

    IPAddress ip(192,168,3,23);
    IPAddress gateway(192,168,3,1);
    IPAddress subnet(255,255,255,0);
    WiFi.config(ip, gateway, subnet);

    Serial.print("\n[+] Static IP forced: ");
    Serial.println(WiFi.localIP());

    WiFi.begin(wifi_network_ssid, wifi_network_password);
    Serial.println("\n[*] Connecting to WiFi Network");

    while(WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(100);
    }

    Serial.print("\n[+] Connected to the WiFi network with local IP : ");
    Serial.println(WiFi.localIP());

    Serial.println("\n[*] Creating ESP32 AP");
    if (!WiFi.softAP(soft_ap_ssid, soft_ap_password, channel, hide_SSID, max_connection))
    {
        Serial.println("failed to start softAP");
    }
    Serial.print("[+] AP Created with IP Gateway ");
    Serial.println(WiFi.softAPIP());
    Serial.print("Soft AP SSID: \"");
    Serial.print(soft_ap_ssid);
    Serial.print("\", IP address: ");
    Serial.println(WiFi.softAPIP());

    if (MDNS.begin("esp32")) Serial.println("MDNS started.");
    else Serial.println("Error! MDNS not started.");

    Serial.println("Starting webserver");
    webserver = new WebServer(80); // responds to either AP or STA connections
    APwebserver = new WebServer(WiFi.softAPIP(),8080);
    STAwebserver = new WebServer(WiFi.localIP(), 8080);
    webserver->on("/", handleWebRequest);
    APwebserver->on("/", handleAPWebRequest);
    STAwebserver->on("/", handleSTAWebRequest);
    webserver->onNotFound(handleDualNotFound);
    APwebserver->onNotFound(handleNotFoundAP);
    STAwebserver->onNotFound(handleNotFoundSTA);
    webserver->begin();
    APwebserver->begin();
    STAwebserver->begin();
    Serial.println("Started webservers");  
}

void loop()
{
  webserver->handleClient();
  APwebserver->handleClient();
  STAwebserver->handleClient();
}

I world not test all with one sketch. test the AP version as the only webserver in the sketch.

MDNS has its own problems with STA/AP. so remove it from the sketch and test only with the IP address.

Argh, got it figured out -- when the phone connects to the IP it pops up saying "mynetname has no internet access -- tap for options" which I was just dismissing because, yeah, that's as expected, no problem. But if I tap that, it says "no internet access -- do you want to stay connected?" Mind you, it stays connected to the AP whether you dismiss this or click "yes", but if you don't click yes on this pop-up, it silently fails to work. Tap "yes" and everything is fine. Thanks for the help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.