Beispiel 1: Einfacher Web-Server mit zwei Seiten aus dem SPIFFS

Dieses Beispiel implementiert zwei einfache Web-Sites "index.html" und "qr.html". Beide Dateien werden ohne weitere Anpassung aus dem SPIFFS geliefert. Weiterhin wird der von UrsAsyncWebServerClass bereit gestellte Handler für nicht vorhandene Ressourcen überschrieben und durch eine Ausgabe auf die Serielle Schnittstelle ergänzt.

ExtremlySimpleWebServer: index.html   ExtremlySimpleWebServer: qr.html   ExtremlySimpleWebServer: not found
index.html   qr.html   not found

Diese Dateien liegen im SPIFFS und sollen hieraus bei Anforderung geladen werden. Hinzu kommen zwei Images: das Favicon ("urs.ico") und der QR-Code als Grafik ("UllisRoboterSeite.png"). Hier die SPIFFS-Struktur:

Verzeichnis "data"

Der Code

Der Code besteht aus der Klasse MyWebServerClass, die die Aufgaben des Web-Servers übernimmt, und dem Hauptprogramm "UrsAsyncWebServerExample1.ino", das die Initialisierung und den Betrieb der Komponenten übernimmt.

MyWebServerClass

Zunächst die Deklaration der Klasse MyWebServerClass, die die Aufgaben des Web-Servers übernimmt. MyWebServerClass ist von UrsAsyncWebServer abgeleitet.

Klassendefinition von MyWebServerClass

// MyWebServer.h
// Einfacher Web-Server
// Behandelt Ressourcen-Bereitstellung aus SPIFFS-Dateien

#ifndef _MYWEBSERVER_h
#define _MYWEBSERVER_h

#include "arduino.h"
#include <UrsAsyncWebServer.h>

class MyWebServerClass : public UrsAsyncWebServer {
protected:
  // Überschreibt die Methode 'notFoundHandler' von 'UrsAsyncWebServer'
  virtual void notFoundHandler(AsyncWebServerRequest *request) override;

public:
  // Initialisiert eine neue Instanz von MyWebServerClass:
  MyWebServerClass(int port = 80) : UrsAsyncWebServer(port) {}

  // Startet den Web-Server:
  void begin(); 
};
#endif

Methode begin

In der Methode begin wird der Web-Server eingerichtet und gestartet. Diese Methode im Detail:

01: void MyWebServerClass::begin() {
02:   // Mögliche Anfragen zur Startseite auf index.html umlenken
03:   rewrite("/index", "/index.html");     // index     -> index.html
04:   rewrite("/index.htm", "/index.html"); // index.htm -> index.html
05: 
06:   // 'urs.ico' mit lebensdauer versehen
07:   serveStatic("/urs.ico", SPIFFS, "/urs.ico", "max-age=3600");
08: 
09:   // alle anderen Dateien aus den SPIFFS, root -> index.html
10:   serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");  
11: 
12:   // Die Basis-Klasse starten
13:   UrsAsyncWebServer::begin(); 
14: 
15:   // Erfolgsmeldung ausgeben
16:   Serial.println("Web-Server gestartet");
17: }

Zeilen 2..4:

Mit der rewrite-Methode können Web-Site-Zugriffe umgelenkt werden. Es gibt verschiedene gebräuchliche Wege, die Start-Seite, in diesem Fall "index.html", aufzurufen. In diesen Zeilen werden die Aufrufe der nicht vorhanden Seiten "index" und "index.htm" umgelenkt auf die vorhandene Datei "index.html".

Zeile 7:

 "/urs.ico" wird auf "/urs.ico" "umgelenkt". Das wäre eigentlich nicht notwendig. Durch Zeile 10 würde das auch erledigt. servstatic bietet aber zusätzlich die Option Cache-Control. Die Angabe "max-age=3600" bewirkt, dass die zugehörige Datei für max. 3600 Sekunden, also eine Stunde, aktuell ist. Gleichzeitig behalten die meisten Browser diese Datei auch dann für eine Stunde im Cache. Hier der Link zur Dokumentation zum Cache-Control beim AsyncWebServer.

Zeile 10:

Mit servstatic wird festgelegt, wie Zugriffe auf URLs behandelt werden sollen, für die keine speziellen Handler definiert sind. serveStatic("/", SPIFFS, "/test") bedeuted z.B.: Abrufe von Dateien im URL-Verzeichnis "/" werden bedient durch gleichnamige Dateien im SPIFFS-Verzeichnis "/test". serveStatic("/", SPIFFS, "/") bewirkt, dass URL-Verzeichnis und SPIFFS-Verzeichnis identisch sein sollen.

Die Angabe ….setDefaultFile("index.html") in Zeile 10 besagt, dass ein Abruf ohne Dateiangabe mit der Ausgabe von "index.html" beantwortet werden soll (s. obigen Screen-Shot, die angegebene URL enthält keine Datei-Angabe).

Zeile 13:

Der Aufruf von begin wird an die Basis-Klasse weiter gereicht.

Methode notFoundHandler

Die Methode notFoundHandler überschreibt die gleichnamige Methode der Basisklasse UrsAsyncWebServer. Es erfolgt eine zusätzliche Ausgabe der nicht gefundenen Ressource auf die serielle Schnittstelle.

01: void MyWebServerClass::notFoundHandler(AsyncWebServerRequest * request) {
02:   UrsAsyncWebServer::notFoundHandler(request);
03:   Serial.printf("Ressource nicht gefunden: %s\n", request->url().c_str());
04: }

Zeile 2:

Es wird zunächst die in der Basisklasse für diesen Fall hinterlegte Methode aufgerufen. Diese gibt eine entsprechende Antwort an den Browser zurück.

Zeile 3:

Die zusätzliche Ausgabe der Bezeichnung der nicht gefundenen Ressource über die serielle Schnittstelle.

Hauptprogramm "UrsAsyncWebServerExample1.ino"

    // ...
01: MyWebServerClass MyWebServer;
02: 
03: void setup() {
04:   Serial.begin(115200);
05:   Serial.println(F("\n----------------------------"));
06:   Serial.println(F("UrsAsyncWebServer Beispiel -1-"));
07: 
08:   UrsWiFi.connectStation(ssid, pw); // Beim WLAN anmelden
09:   MyWebServer.begin();              // Web-Server starten
10: }
11: 
12: void loop() {
13:   // Nichts zu tun
14: }

Zeile 1:

Eine Instanz von MyWebServerClass wird angelegt. Der Port, auf dem der Server lauscht, ist der in der Klasse hinterlegte Default-Port (80).

Zeile 8:

Beim WLAN anmelden. Ich mache es mir einfach und benutze meine Standardmethode aus UrsWifi. ssid und pw sind vorher definierte Zugangsdaten für das WLAN.

Zeile 9:

Der Webserver wird gestartet, Protokolle sollen auf Serial ausgegeben werden.

Zeile 12..14:

In loop ist nichts zu tun. Der Server arbeitet asynchron. Durch die Registrierung der entsprechenden Handler-Methode ist alles notwendige bereits erledigt.

Logging

Das ist die Output an das serielle Terminal:

Termninal-Output

HTML-Seiten

Zur Vollständigkeit die beiden hinterlegten HTML-Seiten

index.html

<!DOCTYPE html>
<html>

<head>
   <meta content="text/html; charset=UTF-8" http-equiv="content-type">
   <title>URS AsyncWebServer Beispiel</title>
   <link href="/urs.ico" rel="shortcut icon" type="image/x-icon">
</head>

<body style="font-family: Arial, Helvetica, sans-serif">

<h1>URS AsyncWebServer Beispiel -1-</h1>

<p>Hier geht es zu <a href="http://ullisroboterseite.de" target="_blank">Ullis Roboter Seite</a>.</p>
<p>Hier geht es zum QR-Code <a href="qr.html" target="_blank">qr.html</a>.</p>

</body>
</html>

qr.html

<!DOCTYPE html>
<html>

<head>
   <meta content="text/html; charset=UTF-8" http-equiv="content-type">
   <title>URS AsyncWebServer Beispiel</title>
   <link href="urs.ico" rel="shortcut icon" type="image/x-icon">
</head>

<body style="font-family: Arial, Helvetica, sans-serif">

<table>
   <tr>
      <td colspan="2" style="text-align: center">

      <h1>URS AsyncWebServer Beispiel</h1>
      </td>
   </tr>
   <tr>
      <td>Hier geht es zu Ullis Roboter Seite:</td>
      <td>
      <a href="http://ullisroboterseite.de" target="_blank">
         <img alt="QR: Ullis Roboter Seite" height="300" src="UllisRoboterSeite.png" 
         title="QR: Ullis Roboter Seite" width="300" style="border-width: 0px"></a>
      </td>
   </tr>
</table>
</body>
</html>

Download

Das Beispiel ist als "UrsAsyncWebServerExample1" in der Bibliotheks-ZIP-Datei enthalten.