Inhaltsverzeichnis
Die Klasse UrsAsyncWebServer vereinfacht die Erstellung eines Web-Servers auf Basis des ESPAsyncWebServer. Einige immer wieder kehrende Aufgaben wurden mit Default-Routinen hinterlegt.
Member | Funktion | Anmerkung |
---|---|---|
UrsAsyncWebServer(int port = 80) | Initialisiert eine neue Instanz der UrsAsyncWebServer-Klasse. | Der Vorgabewert für den Port ist 80, der Standard-Port für HTTP. |
virtual void notFoundHandler (AsyncWebServerRequest *request) | Behandelt den Abruf von Ressourcen, denen kein spezifischer Handler zugewiesen wurde. | Der Default-Handler ruft sendNotFoundResponse auf. |
static void sendNotFoundResponse (AsyncWebServerRequest * request) | Sendet "404, Ressource <URL> nicht vorhanden" an den Anfordernden. | Statische öffentliche Methode, die auch an anderer Stelle abgerufen werden kann. |
void begin(bool initSPIFFS = true) | Startet den Web-Server. | initSPIFFS regelt, ob das SPIFFS initialisiert werden
soll. Zu den Besonderheiten dieser Methode s.u. Methode begin |
void registerWebSite (UrsAsyncWebSite & ws, FileUpload registerStdUploadHandler = FileUpload::asDesigned, WebRequestMethodComposite method = 0) | Registriert eine Web-Site. | Registriert den Request-Handler mit der hinterlegten URL beim AsyncWebServer. Für Details s.u. |
static bool shouldReboot | Wird asynchron gesetzt, wenn das System neu gestartet werden soll. | Vorgabe-Wert ist false. Für Details s. Restart-Steuerung |
Die UrsAsyncWebServer-Klasse entfaltet ihre volle Stärke bei der Verwendung der UrsAsyncWebSite-Klasse. Damit einfach getestet werden kann, legt man zunächst einen rudimentären Web-Server an und erstellt dann nach und nach die einzelnen Seiten. Diese werden in den Web-Server eingefügt.
Für diesen Zweck wird eine neue Klasse von UrsAsyncWebServer abgeleitet. Diese Ableitung benötigt einen Konstruktor, der den TCP-Port festlegt, über den der Server ansprechbar ist. Dann ist es sinnvoll, die Methode begin zu überschreiben. Hier werden die notwendigen Initialisierungsaufrufe untergebracht.
Wenn dann eine Web-Site-Klasse entworfen wurde, legt man am Besten eine Instanz als Member-Variable in der Web-Sever-Klasse an. In begin erfolgt dann die Registrierung dieser Instanz.
Als letztes muss eine Instanz der neuen Server-Klasse angelegt (Arduino-typisch in der .cpp-Datei) und deren Methode begin (typischerweise in setup) aufgerufen werden.
Die folgenden Code-Snippets verdeutlichen diesen Vorgang.
Das Snippet geht davon aus, dass bereits eine Web-Site (myWebSite) angelegt ist.
class MyWebServerClass : public UrsAsyncWebServer { protected: // Web-Site anlegen MyWebSiteClass myWebSite; public: // Initialisiert eine neue Instanz von MyWebServerClass MyWebServerClass(int port = 80) {} // Startet den Web-Server void begin(); };
// Instanz der Klasse veröffentlichen
extern MyWebServerClass MyWebServer;
Es muss lediglich die Methode begin implementiert werden. Wichtig ist am Ende der Methode das Weiterreichen des Aufrufs an die Basis-Klasse UrsAsyncWebServer.
void MyWebServerClass::begin(){
// Web-Sites registrieren (WICHTIG: muss vor serveStatic("/"...) geschehen!)
registerWebSite(myWebSite);
// Weitere Initialisierungsaufgaben erledigen, z.B.:
// Mögliche Anfragen zur Startseite auf index.html umlenken
rewrite("/index", "/index.html"); // index -> index.html
serveStatic("/", SPIFFS, "/"); // alle anderen Dateien aus den SPIFFS
// Web-Server starten, begin() weiterreichen
UrsAsyncWebServer::begin();
}
// Instanz der Klasse anlegen
MyWebServerClass myWebServer;
void setup(){
// ...
myWebServer.begin();
// ...
}
Die Methode UrsAsyncWebServer::begin startet den Server. Die Bereitstellung von Web-Sites als Dateien aus dem SPIFFS funktioniert nur dann, wenn das SPIFFS initialisiert wurde. Diese Methode übernimmt -wider des Vergessens- standardmäßig die Initialisierung. Ein mehrfache Initialisierung des SPIFFS schadet nicht, die SPIFFS-Routinen fangen dies ab.
Des Weiteren wird in der Klasse implementierte "Not-Found-Handler"
registriert. Zuletzt wird mit AsyncWebServer::begin();
der Aufruf an die Basis-Klasse
AsyncWebServer weiter geleitet.
Diese Methode registriert eine Instanz einer von UrsAsyncWebSite abgeleiteten Web-Site-Klasse. Die Methode ist wie folgt deklariert:
void registerWebSite(UrsAsyncWebSite & ws,
FileUpload registerStdUploadHandler = FileUpload::asDesigned,
WebRequestMethodComposite method = HTTP_ANY);
Das erste Argument ws ist die Instanz der Web-Site.
Das zweite Argument registerStdUploadHandler steuert, ob über den in der Klasse UrsAsyncFSHelper definierten File-Upload-Handler ein File-Upload ermöglicht werden soll. Um sprechende Einstellungswerte zu erhalten wurde die Enumeration FileUpload definiert:
// Einstellungswerte für das File-Upload-Verhalten
enum class FileUpload {
none, // Die Seite soll kein Upload unterstützen
allowed, // Die Seite soll ein Upload unterstützen
asDesigned // Upload wie in der Klassendefinition vorgesehen
};
Das dritte Argument method gibt an, welche Request-Typen die Seite bedienen soll. Die Angabe 0 übernimmt den Eintrag aus der Web-Site-Instanz. Ansonsten sind Kombinationen (Oder-Verknüpfung) folgender Konstanten möglich.
Die Methode registriert den Request-Handler für die Seite unter der URL, die durch UrsAsyncWebSite.getUrl bereitgestellt wird. Bei der Registrierung wird berücksichtigt, ob ein File-Upload erlaubt sein soll (s. auch ESPAsyncWebServer: Handlers and how do they work). Die über UrsAsyncWebSite.getRewrites bereit gestellten URL-Alternativen werden ausgewertet und beim ESPAsyncWebServer registriert (s. auch ESPAsyncWebServer: Rewrites and how do they work),
Einige Seiten erlauben es, einen Restart des Prozessors auszulösen. Die Restart-Routinen enthalten indirekt einen Aufruf auf die Methode yield und sind damit im Umfeld des ESPAsyncWebServer nicht erlaubt und führen zum Programmabbruch (unbehandelte Exception). Der Restart muss deshalb im synchronen Programmteil, d.h. in der Methode loop ausgeführt werden.
Soll ein Restart durchgeführt werden, wird vom Request-Handler der betreffenden Seite die Variable UrsAsyncWebServer::shouldReboot auf true gesetzt. Z.B.:
// ...
// POST mit Parameter "reboot" führt zum Neustart
// =======================================================================
if (request->hasParam("reboot", true)) {
UrsAsyncWebServer::shouldReboot = true;
request->send(200, String(), F("Neustart des Servers ausgelöst"));
return; // fertig
}
// ...
In loop wird dann diese Variable überprüft:
void loop() {
// Synchrone Aktionen des Webservers ausführen
// -------------------------------------------------------------------------
if (MyWebServer.shouldReboot) { // Reboot angefordert
Serial.println("Rebooting...");
Serial.flush(); // Ausgabe per Serial abschließen
ESP.restart(); // Reset auslösen
}
//...
}