Closed happytm closed 3 years ago
Hi. Sorry for late reply, I was taking vacations. I'll prepare something for you soon.
Thank you.
/*
Demo1 - this is a minimum you need to do in order to make (only) web server (without websockets) to work
(other demos will follow)
*/
// connect ESP32 in STAtion mode to your WiFi router ...
// ... but don't let ESP32 to set up its own A(ccess) P(oit)
// Callback function that will handle all HTTP requests (since we do not have any file system mounted // to be able to pass .html and other files to client, this callback function is the only possibility // we have to respond to HTTP requests from clients (browsers)
String httpRequestHandler (String& httpRequest, httpServer::wwwSessionParameters *wsp) { // - must be reentrant!
if (httpRequest.substring (0, 6) == "GET / ") {
return String ("Example 01 - dynamic HTML page
return ""; // httpRequestHandler did not handle the request - tell httpServer to handle it internally (404, ...) by returning "" reply }
void setup () { Serial.begin (115200);
startNetworkAndInitializeItAtFirstCall (); // since we do not have any file system mounted this would only start WiFi // but won't initialize network configuration files
// start web server httpServer httpSrv = new httpServer (httpRequestHandler, // our HTTP callback function NULL, // no WS callback function 8 1024, // 8 KB stack size is usually enough, if httpRequestHandler or wsRequestHandler use more stack increase this value until server is stable (char *) "0.0.0.0", // start HTTP server on all available ip addresses 80, // HTTP port NULL); // no firewall callback function if (!httpSrv || (httpSrv && !httpSrv->started ())) Serial.println ("[httpServer] did not start."); }
void loop () {
}
The function that is not displayed correctly looks like this:
/*
Demo2 - this is a minimum you need to do in order to make (only) web server with websockets to work
(other demos will follow)
*/
// connect ESP32 in STAtion mode to your WiFi router ...
// ... but don't let ESP32 to set up its own A(ccess) P(oit)
// Callback function that will handle all HTTP requests (since we do not have any file system mounted // to be able to pass .html and other files to client, this callback function is the only possibility // we have to respond to HTTP requests from clients (browsers)
String httpRequestHandler (String& httpRequest, httpServer::wwwSessionParameters *wsp) { // - must be reentrant! if (httpRequest.substring (0, 6) == "GET / ") { return "\n" "
\n" " RSSIreturn ""; // httpRequestHandler did not handle the request - tell httpServer to handle it internally (404, ...) by returning "" reply }
// Callback function that will handle all WS (websocket) requests - they are always called by web browser from HTML (responses or files - see above)
void wsRequestHandler (String& wsRequest, WebSocket webSocket) { // - must be reentrant! if (wsRequest.substring (0, 16) == "GET /streamRSSI ") { char c; do { delay (1000); int i = WiFi.RSSI (); c = (char) i; } while (webSocket->sendBinary ((byte ) &c, sizeof (c))); // send RSSI information as long as web browser is willing to receive it } }
void setup () { Serial.begin (115200);
startNetworkAndInitializeItAtFirstCall (); // since we do not have any file system mounted this would only start WiFi // but won't initialize network configuration files
// start web server httpServer httpSrv = new httpServer (httpRequestHandler, // our HTTP callback function wsRequestHandler, // our WS callback function 8 1024, // 8 KB stack size is usually enough, if httpRequestHandler or wsRequestHandler use more stack increase this value until server is stable (char *) "0.0.0.0", // start HTTP server on all available ip addresses 80, // HTTP port NULL); // no firewall callback function if (!httpSrv || (httpSrv && !httpSrv->started ())) Serial.println ("[httpServer] did not start."); }
void loop () {
}
/*
Demo3 - mount FAT file system - it is easier to put HTML responses into files than into C variables or literals
select Tools | Partition scheme | one of FAT partition sachems
- we will also need FTP server in order to upload HTML file onto ESP32 FAT file system
(other demos will follow)
*/
// connect ESP32 in STAtion mode to your WiFi router ...
// ... but don't let ESP32 to set up its own A(ccess) P(oit)
// httpRequestHandler HTTP callback function is no longer needed - web server can read its HTTP response from a HTML file
// Callback function that will handle all WS (websocket) requests - they are always called by web browser from HTML (responses or files - see above)
void wsRequestHandler (String& wsRequest, WebSocket webSocket) { // - must be reentrant! if (wsRequest.substring (0, 16) == "GET /streamRSSI ") { char c; do { delay (1000); int i = WiFi.RSSI (); c = (char) i; } while (webSocket->sendBinary ((byte ) &c, sizeof (c))); // send RSSI information as long as web browser is willing to receive it } }
void setup () { Serial.begin (115200);
// FFat.format (); // delete all files if you need to start from scratch mountFileSystem (true); // mount (and format if neccessary) file system
startNetworkAndInitializeItAtFirstCall (); // initialize network configuration files and start network
// start web server httpServer httpSrv = new httpServer (NULL, // no HTTP callback function wsRequestHandler, // our WS callback function 8 1024, // 8 KB stack size is usually enough, if httpRequestHandler or wsRequestHandler use more stack increase this value until server is stable (char *) "0.0.0.0", // start HTTP server on all available ip addresses 80, // HTTP port NULL); // no firewall callback function if (!httpSrv || (httpSrv && !httpSrv->started ())) Serial.println ("[httpServer] did not start.");
// start FTP server
ftpServer *ftpSrv = new ftpServer ("0.0.0.0", // start FTP server on all available ip addresses
21, // controll connection FTP port
NULL); // no firewall callback function
if (!ftpSrv || (ftpSrv && !ftpSrv->started ())) Serial.println ("[ftpServer] did not start.");
}
void loop () {
}
After ESP32 starts you will have to FTP to it and upload index.html into /var/www/html directory (just type anything for username and password). index.html would look like this:
RSSISome tags have disappeared - I'll just upload ZIP file. Demo3.zip
Everything else is packing data into stream of bytes on the server side (ESP32) and parsing the same stream on the client side (javascript in web browser). Now suppose we want to stream samples from A/D converters on pins 36 and 39 each 1/10th of a second. Each sample fits into 16 bit unsigned integer. Therefore each 1/10th of a second ESP32 will push 2, 16 bit unsigned integers (4 bytes) into websocket which will be read by javascript in web browser and parsed into 2 16 bit unsigned integers.
/*
Demo4
*/
// connect ESP32 in STA(tion) mode to your WiFi router ...
// ... but don't let ESP32 to set up its own A(ccess) P(oit)
// httpRequestHandler HTTP callback function is no longer needed - web server can read its HTTP response from a HTML file
// Callback function that will handle all WS (websocket) requests - they are always called by web browser from HTML (responses or files - see above)
void wsRequestHandler (String& wsRequest, WebSocket webSocket) { // - must be reentrant! if (wsRequest.substring (0, 19) == "GET /streamSamples ") { uint16_t buffer [2]; do { delay (100); // 1/10 of a second buffer [0] = (int16_t) analogRead (36); buffer [1] = (int16_t) analogRead (39); } while (webSocket->sendBinary ((byte ) &buffer, sizeof (buffer))); // push 2, 16 bit unsigned integers (4 bytes) into websocket } }
void setup () { Serial.begin (115200);
// FFat.format (); // delete all files if you need to start from scratch mountFileSystem (true); // mount (and format if neccessary) file system
startNetworkAndInitializeItAtFirstCall (); // initialize network configuration files and start network
// start web server httpServer httpSrv = new httpServer (NULL, // no HTTP callback function wsRequestHandler, // our WS callback function 8 1024, // 8 KB stack size is usually enough, if httpRequestHandler or wsRequestHandler use more stack increase this value until server is stable (char *) "0.0.0.0", // start HTTP server on all available ip addresses 80, // HTTP port NULL); // no firewall callback function if (!httpSrv || (httpSrv && !httpSrv->started ())) Serial.println ("[httpServer] did not start.");
// start FTP server
ftpServer *ftpSrv = new ftpServer ("0.0.0.0", // start FTP server on all available ip addresses
21, // controll connection FTP port
NULL); // use firewall callback function for FTP server (replace with NULL if not needed)
if (!ftpSrv || (ftpSrv && !ftpSrv->started ())) Serial.println ("[ftpServer] did not start.");
}
void loop () {
}
index.html could now look something like this:
pin 36Source files are attached in ZIP. Demo4.zip
Thank you for taking so much of your valuable time in order to explain in such a minute detail the concept of servers and the code which make it work. I am sure I will use demo4 for many of my wifi projects in future.
Enjoy :)
This is not an issue.
Thank you for comprehensive multi web server piece of software. I am enjoying testing it.
If time allows can you just create a repository with just websocket server for ESP32?
No FTP server, no HTTP server , no time related code. Just plain websocket server which can communicate with javascript client in web browser and may be display a graph from couple of variables like you show for freeheap and uptime on index page of your Esp32_web_ftp_telnet_server_template.
It should be barebone template where it is simple and people like me can understand and use it in their small project like home automation without complexity of all in one software.
Thank you.