Closed mkeyno closed 8 years ago
sending the first html page to the browser can only be done by a HTTP server. if you have send the first page with some javascript code you can establish a web socket connection to the ESP and load other data if you like.
the first page need to come form a web server, if you not need a standalone system (only ESP) you may can host the page on a local server in the network or on the Internet.
Dear Markus , can you elaborate in details? I have webpages on the SPIFF , when it loaded in the browser, constantly send ajax request to ESP to report back one sensor status , I have slow download for other pages and sometime my poor ESP-01 get chocked and need hardware reset , can you send me example for first HTTP load and then establish websocket link
you can use as base: https://github.com/Links2004/arduinoWebSockets/blob/master/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino
only change the loop too:
unsigned long previousMillis = 0;
const long interval = 250; // update interval
void loop() {
webSocket.loop();
server.handleClient();
unsigned long currentMillis = millis();
if(currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
String data = "SEND DATA to Clients";
webSocket.broadcastTXT(data);
}
}
and it will send all 250ms some data to all connected clients.
Hi Markus @Links2004 , why do we need server.handleClient();
? why webSocket.loop();
cant handle both server and client websocket request ?
also has any one complain or declare any issue with this new last stable version , I've compile your example but it seems my module (nodemuc) never go to running mode , also do you know anyone links or example who elaborate true power of your code
there are two parts the webserver (http) and the websocket server (ws). the "WebSocketServer_LEDcontrol.ino" example has no websocket client init. I use the 2.1.0 of the ESP core and it running fine.
the websocket can do many thinks, on cool example is: https://twitter.com/ESP8266/status/684836968509734913 or http://adityatannu.com/blog/post/2016/01/24/ESP8266-Websockets-demo-using-NeoPixels.html
thanks Markus @Links2004 , one more question , can we establish one connection at time and certify this connection by special cookie and disable any other request to keep the connection healthy and fast?
BR
cookies are not supported, but you can use HTTP Authorization to allow only valide clients access. https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSocketsServer.h#L81
and you can limit the server to one client: https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSocketsServer.h#L31 but when you use Authorization the server will drop all not valide clients so not really needed to limit the client count.
thanks Markus @Links2004 wish you could publish more example of your codes features,
I used following example of platform Arduino 1.64 with last stable version , however nor ESP-12 nor ESP-01 working and issue following error successful software rest
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>
#include <NeoPixelBus.h>
#include <FS.h>
#define pixelCount 16
#define colorSaturation 255
NeoPixelBus strip = NeoPixelBus(pixelCount, 8, NEO_GRB | NEO_KHZ800);
RgbColor red = RgbColor(colorSaturation, 0, 0);
RgbColor green = RgbColor(0, colorSaturation, 0);
RgbColor blue = RgbColor(0, 0, colorSaturation);
RgbColor white = RgbColor(colorSaturation);
RgbColor black = RgbColor(0);
#define USE_SERIAL Serial
const char* ssid = "my SSID";
const char* password = "012345678";
const char* mDNSid = "myWebsocketsTest";
ESP8266WiFiMulti WiFiMulti;
ESP8266WebServer server(80);
//holds the current upload
File fsUploadFile;
WebSocketsServer webSocket = WebSocketsServer(81);
//format bytes
String formatBytes(size_t bytes){
if (bytes < 1024){
return String(bytes)+"B";
} else if(bytes < (1024 * 1024)){
return String(bytes/1024.0)+"KB";
} else if(bytes < (1024 * 1024 * 1024)){
return String(bytes/1024.0/1024.0)+"MB";
} else {
return String(bytes/1024.0/1024.0/1024.0)+"GB";
}
}
String getContentType(String filename){
if(server.hasArg("download")) return "application/octet-stream";
else if(filename.endsWith(".htm")) return "text/html";
else if(filename.endsWith(".html")) return "text/html";
else if(filename.endsWith(".css")) return "text/css";
else if(filename.endsWith(".js")) return "application/javascript";
else if(filename.endsWith(".png")) return "image/png";
else if(filename.endsWith(".gif")) return "image/gif";
else if(filename.endsWith(".jpg")) return "image/jpeg";
else if(filename.endsWith(".ico")) return "image/x-icon";
else if(filename.endsWith(".xml")) return "text/xml";
else if(filename.endsWith(".pdf")) return "application/x-pdf";
else if(filename.endsWith(".zip")) return "application/x-zip";
else if(filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
bool handleFileRead(String path){
Serial.println("handleFileRead: " + path);
if(path.endsWith("/")) path += "index.htm";
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)){
if(SPIFFS.exists(pathWithGz))
path += ".gz";
File file = SPIFFS.open(path, "r");
size_t sent = server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
void handleFileUpload(){
if(server.uri() != "/edit") return;
HTTPUpload& upload = server.upload();
if(upload.status == UPLOAD_FILE_START){
String filename = upload.filename;
if(!filename.startsWith("/")) filename = "/"+filename;
Serial.print("handleFileUpload Name: "); Serial.println(filename);
fsUploadFile = SPIFFS.open(filename, "w");
filename = String();
} else if(upload.status == UPLOAD_FILE_WRITE){
//Serial.print("handleFileUpload Data: "); Serial.println(upload.currentSize);
if(fsUploadFile)
fsUploadFile.write(upload.buf, upload.currentSize);
} else if(upload.status == UPLOAD_FILE_END){
if(fsUploadFile)
fsUploadFile.close();
Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize);
}
}
void handleFileDelete(){
if(server.args() == 0) return server.send(500, "text/plain", "BAD ARGS");
String path = server.arg(0);
Serial.println("handleFileDelete: " + path);
if(path == "/")
return server.send(500, "text/plain", "BAD PATH");
if(!SPIFFS.exists(path))
return server.send(404, "text/plain", "FileNotFound");
SPIFFS.remove(path);
server.send(200, "text/plain", "");
path = String();
}
void handleFileCreate(){
if(server.args() == 0)
return server.send(500, "text/plain", "BAD ARGS");
String path = server.arg(0);
Serial.println("handleFileCreate: " + path);
if(path == "/")
return server.send(500, "text/plain", "BAD PATH");
if(SPIFFS.exists(path))
return server.send(500, "text/plain", "FILE EXISTS");
File file = SPIFFS.open(path, "w");
if(file)
file.close();
else
return server.send(500, "text/plain", "CREATE FAILED");
server.send(200, "text/plain", "");
path = String();
}
void handleFileList() {
if(!server.hasArg("dir")) {server.send(500, "text/plain", "BAD ARGS"); return;}
String path = server.arg("dir");
Serial.println("handleFileList: " + path);
Dir dir = SPIFFS.openDir(path);
path = String();
String output = "[";
while(dir.next()){
File entry = dir.openFile("r");
if (output != "[") output += ',';
bool isDir = false;
output += "{\"type\":\"";
output += (isDir)?"dir":"file";
output += "\",\"name\":\"";
output += String(entry.name()).substring(1);
output += "\"}";
entry.close();
}
output += "]";
server.send(200, "text/json", output);
}
void setColor(RgbColor color, int pixel) {
for (int i=0; i<pixelCount; i++) {
strip.SetPixelColor(i, black);
}
strip.SetPixelColor(pixel, color);
strip.Show();
}
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {
switch(type) {
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\n", num);
break;
case WStype_CONNECTED: {
IPAddress ip = webSocket.remoteIP(num);
Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
// send message to client
webSocket.sendTXT(num, "Connected");
}
break;
case WStype_TEXT:
Serial.printf("[%u] get Text: %s\n", num, payload);
if(payload[0] == '#') {
// we get RGB data
// decode rgb data
uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);
// NeoPixels
for (int i=0; i<pixelCount; i++) {
strip.SetPixelColor(i, RgbColor(((rgb >> 16) & 0xFF), ((rgb >> 8) & 0xFF),((rgb >> 0) & 0xFF) ));
}
strip.Show();
}
if(payload[0] == '*') {
// we get Pixel number
uint32_t PixelNumber = (uint32_t) strtol((const char *) &payload[1], NULL, 16);
// NeoPixels
for (int i=0; i<pixelCount; i++) {
strip.SetPixelColor(i, RgbColor(0x00, 0x00,0x00));
}
strip.SetPixelColor(PixelNumber, RgbColor(0xff, 0xff,0xff));
strip.Show();
}
break;
}
}
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println("Starting...........");
for(uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
SPIFFS.begin();
{
Dir dir = SPIFFS.openDir("/");
while (dir.next()) {
String fileName = dir.fileName();
size_t fileSize = dir.fileSize();
Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
}
Serial.printf("\n");
}
WiFiMulti.addAP(ssid, password);
while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
Serial.println("");
Serial.print("Connected! IP address: "); Serial.println(WiFi.localIP());
// start webSocket server
webSocket.begin();
webSocket.onEvent(webSocketEvent);
// Set up mDNS responder:
if (!MDNS.begin(mDNSid)) {
Serial.println("Error setting up MDNS responder!");
while(1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
Serial.print("Open http://");
Serial.print(mDNSid);
Serial.println(".local/edit to see the file browser");
//SERVER INIT
//list directory
server.on("/list", HTTP_GET, handleFileList);
//load editor
server.on("/edit", HTTP_GET, [](){
if(!handleFileRead("/edit.htm")) server.send(404, "text/plain", "FileNotFound");
});
//create file
server.on("/edit", HTTP_PUT, handleFileCreate);
//delete file
server.on("/edit", HTTP_DELETE, handleFileDelete);
//first callback is called after the request has ended with all parsed arguments
//second callback handles file uploads at that location
server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload);
//called when the url is not defined here
//use it to load content from SPIFFS
server.onNotFound([](){
if(!handleFileRead(server.uri()))
server.send(404, "text/plain", "FileNotFound");
});
server.begin();
Serial.println("HTTP server started");
// Add service to MDNS
MDNS.addService("http", "tcp", 80);
MDNS.addService("ws", "tcp", 81);
// Initialize NeoPixel Strip
strip.Begin();
strip.Show();
}
void loop() {
webSocket.loop();
server.handleClient();
}
`
error
`
ets Jan 8 2013,rst cause:4, boot mode:(3,6)
wdt reset
load 0x4010f000, len 1264, room 16
tail 0
chksum 0x42
csum 0x42
~ld
hi Markus , I have webserver sketch which is serve about 500 kb html file in SPIFF, if I use the only HTTP webserver , the latency is long , the download is so slow and somehow the module cant understand which client is main and chocked by request of other clients, however your suggestion to using ESPAsyncTCP & ESPAsyncWebServer was not successful so I thought maybe we could use webserver to create the secure long stand single connection with client and whereas the connection is live the module can check sensor status in loop
any replay appreciated