Dal mio Wemos chiamo un file ad un indirizzo per vedere se è a ZERO oppure a UNO.
Succede che questo sito è diventato https e il Wemos non riesce più a leggere con la chiamata GET, cosa che funziona benissimo se io faccio www.miosito.it/public/BB/miofile.txt
La riprova è che se io forzo il sito in http la chiamata torna a funzionare.
Mentre adesso, con https non funziona più.
Se faccio un Serial.print della risposta mi da
HTTP/1.1 301 Moved Permanently
Date: Thu, 23 Dec 2021 08:41:36 GMT
Server: Apache
Location: https://www.miosito.net/public/BB/5.txt
Content-Length: 251
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://www.miosito.net/public/BB/5.txt">here</a>.</p>
</body></html>
Niente da fare.
Non è così facile, da quanto ho letto: il Wemos con il sito web devono scambiarsi i certificati SSL e la cosa non è per niente semplice
Con ESP8266, se non ti interessa la verifica del certificato, puoi impostare la connessione come "insecure" usando però il client WiFiClientSecure.
Le connessioni HTTPS però sono solo sulla porta 443, mentre tu stai usando la 80 che è solo HTTP
Se invece vuoi usare il certificato, lo devi prima recuperare dal sito web in formato base64 (basta un browser) e poi impostarlo nel client (come un char array)
No, non lo conoscevo.
Io uso direttamente il browser e poi esporto il certificato se ho bisogno del formato base 64.
Basta fare click sull'icona a forma di lucchetto vicino all'indirizzo, poi visualizza certificato e quindi esporta.
Di solito conviene, risalire la catena di autorizzazioni ed inserire il certificato della certification authority (Go Daddy, Cloudflare etc et c) perché ha una durata maggiore rispetto a quello del singolo sito (tipicamente decine di anni)
Non sono ancora riuscito a fare quest'operazione direttamente dagli ESP
Il file del certificato si potrebbe anche caricare direttamente dalla flash volendo, questo potrebbe essere una buon compromesso.
... allora ricordavo male, comunque era un link che era stato dato qui, su un post del forum Italiano ed è piuttosto comodo, ti prepara già tutto lui il pezzo di codice ... devi fare solo copia/incolla
E' abbastanza normale perché anche se lato ESP decidi di non verificare il certificato, tutto l'handshake necessario per instaurare una connessione HTTPS rimane.
Inoltre i dati viaggiano crittografati mentre prima era tutto in chiaro ed anche questo richiede un minimo di tempo di elaborazione in più.
Puoi ridurre un pochino i tempi usando le sessioni. Dai uno sguardo all'esempio BearSSL_session.ino
Ho fatto una prova al volo con setInsecure + sessione con un server HTTPS remoto (Telegram) facendo una richiesta ogni 30 secondi e sono passato da circa 1400/1500 ms senza sessione a circa 1000/1100 ms.
Poco, ma meglio di niente!
Un modo molto più efficace per aumentare la velocità di connessione, è quello di non chiudere il socket TCP immediatamente dopo la richiesta con l'istruzione client.stop();
E' necessario anche rimuovere l'eventuale header "Connection: close" perché altrimenti sarà il server una volta elaborata la richiesta a chiudere. Modica o aggiungi l'header in "Connection: Keep-Alive".
La connessione ad un certo punto verrà comunque interrotta, ma testando se c'è ancora connessione la puoi ristabilire nuovamente (dipende dal server, con Telegram ad esempio accade tipo ogni 5 minuti).
Sempre con l'esempio di cui sopra, i tempi sono passati a circa 300/400 ms.
N.B.
Negli esempi di solito inseriscono un delay() o un while tra la richiesta HTTP e la successiva lettura dati, io invece ho usato una variabile bool perché odio gli algoritmi bloccanti (anche se questo esempio lo è voltuamente alla fine).
#include <ESP8266WiFi.h>
const char* ssid = "xxxxxxxxxx";
const char* password = "xxxxxxxxxx";
const char* host = "api.telegram.org";
const uint16_t port = 443;
#define STARS "\n**************************\n"
// Use WiFiClient class to create TCP connections
WiFiClientSecure client;
BearSSL::Session session;
void setup() {
Serial.begin(115200);
Serial.printf("Connecting to %s\n", ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nWiFi connected. IP address: ");
Serial.println(WiFi.localIP());
client.setInsecure();
client.setSession(&session);
}
void loop() {
static bool doDelay;
static bool waitData;
static uint32_t startTime;
if (!client.connected()) {
startTime = millis();
Serial.printf("Connecting to %s:%d\n", host, port);
if (!client.connect(host, port)) {
client.stop();
Serial.println("connection failed");
}
waitData = false;
Serial.printf(STARS"Connection time: %dms"STARS, millis() - startTime);
}
if (client.connected() && !waitData) {
startTime = millis();
client.println("GET /botxxxxxxxx:AAGhC7lD2_lLWhRlkoQcnrranavca8rPrfM/getMe HTTP/1.0");
client.println("Host: api.telegram.org");
client.println("Connection: Keep-Alive");
client.println();
waitData = true; // waiting for data to be available
}
if (client.available()) {
while (client.available()) {
char ch = static_cast<char>(client.read());
Serial.print(ch);
}
waitData = false;
Serial.printf(STARS"HTTP GET request time: %dms"STARS, millis() - startTime);
}
//client.stop();
doDelay = true;
// Do nothing only if not waiting for HTTP data
if (doDelay && !waitData) {
delay(30000);
doDelay = false;
}
}
sono velocissime !!!
Vado a leggere 2 files nel web in pochi centesimi mentre prima, col sistema classico in HTTP, ogni lettura di file mi portava via 6 secondi.
Ho visto che è meglio non usare, alla fine del loop:
https.end();
newSecure.stop();
E' molto più veloce, ma non so se porta degli "effetti collaterali".
Prova a tenere sotto controllo lo stato dell'heap.
Con ESP32 io ci sono diventato matto, perché ogni volta che aprivo una nuova connessione "sparivano" alcuni byte disponibili perché il buffer allocato non veniva recuperato correttamente.
Con ESP8266 invece non ho mai riscontrato questi problemi, ad ogni modo una verifica non guasta.
Io di solito aggiungo questa funzione (buona per tutte e due le piattaforme) nel loop() nella fase di debug: