Techniques "avancées" de serveur web sur ESP8266

Le code une fois que l'on comprend cela n'est pas sorcier:(le modifier pour avoir votre SSID et mot de passe)

#include "FS.h" // pour le SPIFFS
const char * nomDeFichier = "/basic.html";

const byte pinBouton = D3;

// provient de https://github.com/esp8266/Arduino
// télécharger et installer à la main la dernière version
#include <ESP8266WiFi.h>


const char* ssid = "*******";
const char* password = "*******";

const uint16_t HTTPPort = 80;
WiFiServer serveurWeb(HTTPPort); // crée un serveur sur le port HTTP standard

const byte maxHTTPLine = 100;
char httpLine[maxHTTPLine + 1]; // +1 pour avoir la place du '\0'

const byte maxURL = 50;
char urlRequest[maxURL + 1]; // +1 pour avoir la place du '\0'


void printHTTPServerInfo()
{
  Serial.print(F("Site web http://")); Serial.print(WiFi.localIP());
  if (HTTPPort != 80) {
    Serial.print(F(":"));
    Serial.print(HTTPPort);
  }
  Serial.println();
}

void envoyerEtatBouton(WiFiClient &cl)
{
  if (digitalRead(pinBouton) == LOW) {
    cl.println(F("actif"));
  }
  else {
    cl.println(F("inactif"));
  }
}

boolean testRequeteWeb()
{
  boolean requeteHTTPRecue = false;
  byte indexMessage = 0;
  char * ptrGET, *ptrEspace;

  WiFiClient client = serveurWeb.available();
  if (!client) return requeteHTTPRecue; // pas de client connecté
  boolean currentLineIsBlank = true;
  while (client.connected()) {
    if (client.available()) {
      char c = client.read();
      Serial.print(c);
      if (c == '\n' && currentLineIsBlank) { // une requête HTTP se termine par une ligne vide

        // ON GENERE LA PAGE WEB
        if (strcmp(urlRequest, "/favicon.ico")) { // si ce n'est pas pour le favicon
          requeteHTTPRecue = true;

          // On envoie un en tête de réponse HTTP standard
          client.println("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: keep-alive\r\n");

          // on regarde si on a une requete qui continet /reqEtatBouton ( sinon on renvoie toute la page)
          if (strstr(urlRequest, "/reqEtatBouton")) { // http://www.cplusplus.com/reference/cstring/strstr/?kw=strstr
            // on va lire l'état du bouton et on renvoie l'information correctement
            envoyerEtatBouton(client);
          } else { // on envoie la page web par défaut
            if (SPIFFS.exists(nomDeFichier)) {
              File pageWeb = SPIFFS.open(nomDeFichier, "r");
              client.write(pageWeb);
              pageWeb.close();
            } else {
              Serial.println(F("Erreur de fichier"));
            }
          }
        }
        break;           // on sort du while et termine la requête
      } // fin de génération de la réponse HTTP

      if (c == '\n') {
        currentLineIsBlank = true;
        httpLine[indexMessage] = '\0'; // on termine la ligne correctement (c-string)
        indexMessage = 0; // on se reprépre pour la prochaine ligne
        if (ptrGET = strstr(httpLine, "GET")) {
          // c'est la requête GET, la ligne continent "GET /URL HTTP/1.1", on extrait l'URL
          ptrEspace = strstr(ptrGET + 4, " ");
          *ptrEspace = '\0';
          strncpy(urlRequest, ptrGET + 4, maxURL);
          urlRequest[maxURL] = '\0'; // par précaution si URL trop longue
        }
      } else if (c != '\r') {
        currentLineIsBlank = false;
        if (indexMessage <= maxHTTPLine - 1) {
          httpLine[indexMessage++] =  c; // sinon on ignore le reste de la ligne
        }
      }
    } // end if available
  } // end while
  delay(1);
  client.stop(); // termine la connexion
  return requeteHTTPRecue;
}


void setup() {

  pinMode(pinBouton, INPUT_PULLUP);

  Serial.begin(74880); // parce que mon Wemos et par défaut à peu près à cette vitesse, évite les caractères bizarre au boot
  Serial.println("\n\nTest SPIFFS\n");

  // on démarre le SPIFSS
  if (!SPIFFS.begin()) {
    Serial.println("erreur SPIFFS");
    while (true); // on ne va pas plus loin
  }

  WiFi.begin(ssid, password);

  Serial.println();
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.write('.');
  }
  Serial.println();

  // on démarre le serveur
  serveurWeb.begin();
  printHTTPServerInfo();

}

void loop() {
  testRequeteWeb();
}

Si vous chargez ce code dans votre ESP, puis que vous ouvrez la console Série vous allez voir

—————————————————————

```
ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v303a71de
~ld

Test SPIFFS

.
Site web http://192.168.1.46
```

—————————————————————

ouvrez un navigateur web et tapez votre URL (ici pour moi

http://192.168.1.46

)

vous verrez défiler dans la console Série la requête HTTP (car j'imprime chaque caractère reçu)

—————————————————————

</sub> <sub>GET / HTTP/1.1 <<--- on voit que la requête HTTP est pour l'URL "/" Host: 192.168.1.46 Connection: keep-alive Upgrade-Insecure-Requests: 1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5 Accept-Language: fr-fr DNT: 1 Accept-Encoding: gzip, deflate</sub> <sub>
<<--- ici il y a la ligne vide
—————————————————————

Comme on a demandé la racine du site web (URL est "/") on retourne le fichier basic.html et c'est ce que l'on voit dans le navigateur

step1.png

clickez maintenant sur le bouton dans la page web. Vous verrez défiler dans le console Série le text suivant

—————————————————————

</sub> <sub>GET [color=green]/reqEtatBouton&aleatoire=420484[/color] HTTP/1.1 Host: 192.168.1.46 Accept-Encoding: gzip, deflate Connection: keep-alive Accept: */* User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5 Accept-Language: fr-fr Referer: http://192.168.1.46/ DNT: 1</sub> <sub>
<<--- ici il y a la ligne vide
—————————————————————

On voit bien qu'on a reçu une requête HTTP en provenance de notre javaScript pour l'URL "[color=green]/reqEtatBouton&aleatoire=420484[/color]", qui est donc bien composée de "/reqEtatBouton" suivi de la partie qu'on construit aléatoirement pour éviter le problème de cache.

votre navigateur affichera sans tout recharger que le bouton est inactif

step2.png

Tenez maintenant appuyé le bouton sur votre breadboard et appuyez à nouveau sur le bouton dans la page web

Vous verrez défiler dans le console Série le text suivant

—————————————————————

GET /reqEtatBouton&aleatoire=326319 HTTP/1.1
Host: 192.168.1.46
Accept-Encoding: gzip, deflate
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0.1 Safari/604.3.5
Accept-Language: fr-fr
Referer: http://192.168.1.46/
DNT: 1


—————————————————————

On voit bien qu'on a reçu une requête HTTP en provenance de notre javaScript pour l'URL "[color=green]/reqEtatBouton&aleatoire=326319[/color]", qui est donc bien composée de "/reqEtatBouton" suivi de la partie aléatoire qui a bien changé par rapport à la précédente

votre navigateur affichera sans tout recharger que le bouton est actif

step3.png