Где определить функции обратного вызова веб-сервера, чтобы они могли получить доступ к объекту сервера? (библиотека ESP8266WebServer)

Я хочу, чтобы мое устройство на базе ESP8266 создало точку доступа, позволяющую пользователю вводить свой домашний ssid и пароль. Существует объект устройства, который содержит большую часть данных, определенных в другом месте.

Я пытаюсь использовать библиотеку ESP8266WebServer. Это требует от меня определения функций обратного вызова без параметров. Где мне следует объявить и определить эти функции обратного вызова, чтобы они могли получить доступ к объекту сервера? Во всем примере кода объект сервера является глобальным. Я бы хотел этого избежать, а также не хотел бы, чтобы объект сервера был постоянным членом класса Device.

Как мне это сделать? Не разрешено определять функции обратного вызова внутри Device::getWifiCredentials, и если я объявлю их снаружи, сервер выйдет за пределы области действия.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// Функция создания точки доступа для получения ssid и пароля
int Device::getWifiCredentials() {

    ESP8266WebServer server(80);
    server.begin();
    
    // определяем обратные вызовы
    server.on("/", handleRoot); // начальная страница

    server.on("/ssid", handleCredentials); // перехватываем ответ с начальной страницы

    // ждем доставки учетных данных
    server.handleClient();

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

    return ACTION_SUCCESSFUL;

}

// **Где можно определить эти функции, чтобы разрешить им доступ к объекту сервера?**

void handleRoot() {
};

void handleCredentials() {

    String ssid;
    String pw;

    if( server.hasArg() ){
        ssid = server.arg("ssid");
        pw = server.arg("pw");
    }
};

, 👍3

Обсуждение

«Не разрешено определять функции обратного вызова внутри Device::getWifiCredentials», это можно сделать с помощью анонимной функции, такой как server.on("/ssid", []() { }., @hcheung

я бы переместил ESP8266WebServer server(80); на 4-ю строку; вне какой-либо функции. Я думаю, вам, возможно, придется вызвать on() перед Begin(), только один раз, как в setup(), по крайней мере, у меня так работает., @dandavis


1 ответ


2

поместите объявление сервера за пределы конструктора и вызовите обратный вызов класса:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server(80);

// Функция создания точки доступа для получения ssid и пароля
int Device::getWifiCredentials() {
server.begin();
    
    // определяем обратные вызовы
    server.on("/", std::bind(&Device::handleRoot, this); // начальная страница

    server.on("/ssid", std::bind(&Device::handleCredentials, this); // перехватываем ответ с начальной страницы

    // ждем доставки учетных данных
    server.handleClient();

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

    return ACTION_SUCCESSFUL;
}
,