发出加载文件w / SPIFFS(ERR_CONTENT_LENGTH_MISMATCH)

时间:2016-06-08 19:56:08

标签: websocket arduino webserver client-server esp8266

好吧所以我过去两天一直在研究这个问题,但我仍然觉得自己无处可去。

我最近开始在 HUZZAH ESP8266 上使用 SPIFFS文件系统进行 Arduino 开发,例如 FSBrowser.ino 例如,虽然在分离代码方面做得很好,但随着我的代码不断增长,它在稳定性方面并不是很好。

自从我开始添加越来越多的javascript以来,我开始为各种文件弹出错误,无论是我的HTML / CSS / JS,我看到的主要错误是 ERR_CONTENT_LENGTH_MISMATCH 。 / p>

primary error

//File Read for File System
bool handleFileRead(String path)
{
  if(mySerial)  
    mySerial.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");

    if(mySerial)
        mySerial.println("TEST: " + path + " FILE OPEN: " + file.size());

    size_t sent = server.streamFile(file, contentType);

    if(mySerial)
        mySerial.println("TEST: " + path + " SIZE: " + file.size());

    file.close();

    if(mySerial)
        mySerial.println("TEST: " + path + " FILE CLOSE");

    return true;
  } //end if 
  return false;
} //end function handleFileRead

所以在那之后我开始检查我从FSBrowser.h示例中复制的handleFileRead()函数,并且在测试了各种print语句后,似乎挂起发生在这一行中:

size_t sent = server.streamFile(file,contentType);

template<typename T> size_t streamFile(T &file, const String& contentType){
  setContentLength(file.size());
  if (String(file.name()).endsWith(".gz") &&
      contentType != "application/x-gzip" &&
      contentType != "application/octet-stream"){
    sendHeader("Content-Encoding", "gzip");
  }
  send(200, contentType, "");
  return _currentClient.write(file, HTTP_DOWNLOAD_UNIT_SIZE);
}

所以从那里开始,我进入了 ESP8266WebServer.h ,找到了 streamFile()函数。进入这个函数后,我发现了这一行:

返回_currentClient.write(file,HTTP_DOWNLOAD_UNIT_SIZE);

由此我推断出两件事:

  • HTTP_DOWNLOAD_UNIT_SIZE(在1460定义)存在下载限制上限。
  • 此函数调用名为 write() WiFiClient 类中的另一个函数。

所以我跟踪了这​​个函数: size_t WiFiClient :: write(const uint8_t * buf,size_t size)。

size_t WiFiClient::write(const uint8_t *buf, size_t size)
{

    SoftwareSerial mySerial(12,13); 

    mySerial.begin(115200);

    if(mySerial)
    {
        mySerial.print("Size: ");
        mySerial.println(size);
    }

    if (!_client || !size)
    {
        if(mySerial)
            mySerial.println("FAILURE");

        return 0;
    }

        if(mySerial)
            mySerial.println("SUCCESS");

    return _client->write(reinterpret_cast<const char*>(buf), size);
}

现在这不完全匹配,因为调用的write()函数的第一个参数是文件类型,而此函数的第一个参数是uint8_t,但是我放了一些打印尽管如此,这里的语句会在文件加载时执行,所以我相信我找到了正确的函数。

然而,现在我不知道如何从这里继续修复问题,因为只有一个递归调用并且错误似乎发生,因为罪魁祸首文件没有完成加载(至少根据chrome调试器的网络选项卡)

debugger network tab

如您所见,style.css文件被列为 3千字节,这当然是错误的:我的css文件 27千字节

所以看起来加载文件存在问题(这不是css文件独有的,它也发生在我的javascript文件中,似乎是随机的)。我已经尝试缩小所有文件,但它没有解决问题;所以我真的可以帮助确定如何解决这个问题。

现在我收到了其他来源的一些建议,尝试使用此库,这是 FSBrowser 代码的修改版本:https://github.com/me-no-dev/ESPAsyncWebServer

起初这似乎解决了我所有的问题。代码运行稳定,没有出现任何先前的问题。但是,自从切换到该库以来,我遇到了无数新问题:

new issues

最奇怪的事情发生了,似乎有些代码丢失了?

missing code

如果查看该照片中红色突出显示的行,您可以看到在removeClass()语句的中间,它会停止拼写出类(“deactiveSect”)并进一步启动一个完全不同的if语句在代码中。

然而,目前服务器上的代码部分相同:

code on server

你可以看到它似乎合并了第66和70行。

因此,虽然我使用的FSBrowser代码版本无法处理我正在使用的代码级别,但如果无数问题不断发生,我无法看到如何使用此修改后的库

这是我的其余代码(使用原始FSBrowser库)的源代码:

主要ino文件

//Header File
#include "HHIO_Portal.h"

//Function used to verify incoming information from the teensy to the wifi card via the communication protocol
void recInfoWifi()
{
    /*
    ===============================
    COMMUNICATION PROTOCOL - Removed due to post size limit
    ===============================
    */

} //end comProtocolWifi

//Function used to send information to the teensy in order to control the HHIO PTT
void sendInfoWifi()
{
    unsigned long currTime = millis();

    //SEND
    if(currTime - prevTimeTest > testInterval)   
    {
        prevTimeTest = currTime; 

        //Test Message
        messageLength = 3;
        subsys = SUBSYS_DBG;

        messageContent = wifiCounter; 

        //Teensy Console
        Serial.write(som);
        Serial.write(messageLength);
        Serial.write(subsys);
        Serial.write(messageContent);
        Serial.write(eom);

        wifiCounter++;

    } //end if (RECEIVE INFO)
} //end function sendInfoWifi

void setup()
{ 
  //Initiate Serial connection to Teensy
  Serial.begin(115200);

  //This is for debugging/housekeeping (And all console messages that use mySerial as opposed to Serial)
  mySerial.begin(115200);

  /*
  ===============================
  FILE SYSTEM
  ===============================
  */
  SPIFFS.begin();
  {
    Dir dir = SPIFFS.openDir("/");
    while (dir.next()) {    
      String fileName = dir.fileName();
      size_t fileSize = dir.fileSize();
      if(mySerial)
        mySerial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str()); 
    } //end while
        if(mySerial)
            mySerial.printf("\n"); 
  } //end SPIFFS BEGIN  

  /*
  ===============================
  WIFI INIT
  ===============================
  */
  if(mySerial)
    mySerial.printf("Connecting to %s\n", ssid); 

  //Make the initial Wifi connection
  if (String(WiFi.SSID()) != String(ssid)) {
    WiFi.begin(ssid, password);
  } //end if

 //Wait for the Wifi to finish connecting
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if(mySerial)
      mySerial.print("."); 
  } //end while

  //IP Address for webpage
  if(mySerial)
  {
      mySerial.println(""); 
      mySerial.print("Connected! IP address: "); 
      mySerial.println(WiFi.localIP()); 
  } //end if

  //Might not need this
  MDNS.begin(host);

  //Hostname for webpage
  if(mySerial)
  {
    mySerial.print("Open http://"); 
    mySerial.print(host); 
    mySerial.println(".local/edit to see the file browser"); 
  } //end if


  /*
  ===============================
  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");
  });

  //get heap status, analog input value and all GPIO statuses in one json call
  server.on("/all", HTTP_GET, [](){
    String json = "{";
    json += "\"heap\":"+String(ESP.getFreeHeap());
    json += ", \"analog\":"+String(analogRead(A0));
    json += ", \"gpio\":"+String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
    json += "}";
    server.send(200, "text/json", json);
    json = String();
  });

  //Start the server
  server.begin();

  if(mySerial)  
    mySerial.println("HTTP server started"); 

  //Open the websocket connection in order to update the status values on the page without refreshing
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
} //end Setup

void loop()
{   
    //SEND INFO TO TEENSY
    sendInfoWifi();

    //RECEIVE INFO FROM TEENSY
    recInfoWifi();

    //CONTINUE WEBSOCKET CONNECTION
    webSocket.loop();

    //SERVE WEBPAGE TO THE USER
    server.handleClient();
} //end loop

主要ino头文件

//Initiate necessary libraries
#include <SoftwareSerial.h>
#include <HHIO_Subsystems.h>
#include <ESP8266WiFi.h>
//#include <pfodESP8266WiFi.h>
#include <WebSocketsServer.h>
//#include <pfodESP8266WebServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <FS.h>

//Serial connection for debugging (RX, TX)
SoftwareSerial mySerial(12,13); 

//SSID/Pass/Host
const char* ssid = "*****";
const char* password = "*****";
const char* host = "esp8266fs";

//Setup File System Connection
MDNSResponder mdns;

//Web Server
ESP8266WebServer server(80);

//File System 
File fsUploadFile;

//Websocket
WebSocketsServer webSocket = WebSocketsServer(81);

//Invalid Message
uint8_t invalidMessageFlag = 0;

//Counter for testing serial connection
uint8_t wifiCounter = 0;

//Com. Protocol Buffer
uint8_t rxBuff[256];

//Start of Message
uint8_t som = 0x11;

//End of Message
uint8_t eom = 0x12;

//Subsystem variables
uint8_t subsys; 
uint8_t receivedSubsys;

//Read Byte for Com. Protocol
uint8_t rx_byte = 0x00;

//Message length variables
uint8_t messageLength = 0;
uint8_t receivedMessageLength = 0;

//Message content variable
uint8_t messageContent;

//Variable to check incoming serial content
uint8_t serialCurrent; 

//Counter used for verifying the som variable
int initialCounter = 0;

//Message progression variables
boolean messageBegun = false; 
boolean messageInProgress = false;

//Variables currently used to read status info coming from the teensy (CURRENTLY RANDOMIZED INFO)
int currNumRefresh = 0;
int currMicroC = 0;
int currMicroD = 0;
int currMicroE = 0;
int currPressureC = 0; 
int currPressureD = 0; 
int currPressureE = 0; 
int currValveStatusNumC = 0; 
int currValveStatusNumD = 0; 
int currValveStatusNumE = 0;
int currFluid = 0;

//Buffer for sending information from Arduino to the webpage
char statusbuf[256]; 

//Valve 1
String valveStatusC = "Closed";
String valveTubePropsC = "175px solid #00ADEF";
String valveColorC = "red";

//Valve 2
String valveStatusD = "Closed";
String valveTubePropsD = "175px solid #00ADEF";
String valveColorD = "red";

//Valve 3
String valveStatusE = "Closed";
String valveTubePropsE = "175px solid #00ADEF";
String valveColorE = "red";

//Variables for sending test message to teensy
long prevTimeTest = 0;
long testInterval = 5000;

//Format Bytes
String formatBytes(size_t bytes){

  if(mySerial)  
    mySerial.println("formatBytes FUNC");

  if (bytes < 1024){
    return String(bytes)+"B";
  } //end if 

  else if(bytes < (1024 * 1024)){
    return String(bytes/1024.0)+"KB";
  } //end else if

  else if(bytes < (1024 * 1024 * 1024)){
    return String(bytes/1024.0/1024.0)+"MB";
  } //end else if
  else {
    return String(bytes/1024.0/1024.0/1024.0)+"GB";
  } //end else
} //end function formatBytes

//Content Type for File System
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";

  if(mySerial)  
    mySerial.println("getContentType FUNC");

  return "text/plain";
} //end function getContentType

//File Read for File System
bool handleFileRead(String path)
{
  if(mySerial)  
    mySerial.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");

    if(mySerial)
        mySerial.println("TEST: " + path + " FILE OPEN: " + file.size());

    size_t sent = server.streamFile(file, contentType);

    if(mySerial)
        mySerial.println("TEST: " + path + " SIZE: " + file.size());

    file.close();

    if(mySerial)
        mySerial.println("TEST: " + path + " FILE CLOSE");

    return true;
  } //end if 
  return false;
} //end function handleFileRead

//File Upload for File System
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;
    if(mySerial)
    {
        mySerial.print("handleFileUpload Name: "); 
        mySerial.println(filename);
    } //end if

    fsUploadFile = SPIFFS.open(filename, "w");
    filename = String();
  } //end if 
  else if(upload.status == UPLOAD_FILE_WRITE)
  {
    if(mySerial)
    {
        mySerial.print("handleFileUpload Data: "); 
        mySerial.println(upload.currentSize);
    } //end if

    if(fsUploadFile)
      fsUploadFile.write(upload.buf, upload.currentSize);
  } //end else if
  else if(upload.status == UPLOAD_FILE_END)
  {
    if(fsUploadFile)
      fsUploadFile.close();
    if(mySerial)
    {
        mySerial.print("handleFileUpload Size: "); 
        mySerial.println(upload.totalSize);
    } //end if
  } //end else if
} //end function handleFileUpload

//File Delete for File System
void handleFileDelete()
{
  if(server.args() == 0) return server.send(500, "text/plain", "BAD ARGS");
  String path = server.arg(0);
  if(mySerial)
    mySerial.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();
} //end function handleFileDelete

//File Create for File System
void handleFileCreate()
{
  if(server.args() == 0)
    return server.send(500, "text/plain", "BAD ARGS");
  String path = server.arg(0);
  if(mySerial)
      mySerial.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();
} //end function handleFileCreate

void handleFileList() 
{
  if(!server.hasArg("dir")) 
  {
      server.send(500, "text/plain", "BAD ARGS"); 
      return;
  } //end if

  String path = server.arg("dir");
  if(mySerial)
    mySerial.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();
  } //end while

  output += "]";
  server.send(200, "text/json", output);
} //end function handleFileList

//HHIO PTT POWER LED ON
void switchPOWERon() {

    int powerStatusLength = 1;

    subsys = SUBSYS_1; 

    //Account for the end of message
    messageLength = powerStatusLength + 2;

    messageContent = 1;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchPOWERon

//HHIO PTT POWER LED OFF
void switchPOWERoff() {

    int powerStatusLength = 1;

    subsys = SUBSYS_1; 

    //Account for the end of message
    messageLength = powerStatusLength + 2;

    messageContent = 0;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchPOWERoff

//PUMP POWER ON
void pumpPOWERon() {

    int pumpPowerStatusLength = 1;

    subsys = SUBSYS_2; 

    //Account for the end of message
    messageLength = pumpPowerStatusLength + 2;

    messageContent = 1;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchPOWERon

//PUMP POWER OFF
void pumpPOWERoff() {

    int pumpPowerStatusLength = 1;

    subsys = SUBSYS_2; 

    //Account for the end of message
    messageLength = pumpPowerStatusLength + 2;

    messageContent = 0;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchPOWERoff

//LED POWER ON
void switchLEDon() {

    int ledStatusLength = 1;

    subsys = SUBSYS_3; 

    //Account for the end of message
    messageLength = ledStatusLength + 2;

    messageContent = 1;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchLEDon

//LED POWER OFF
void switchLEDoff() {

    int ledStatusLength = 1;

    subsys = SUBSYS_3; 

    //Account for the end of message
    messageLength = ledStatusLength + 2;

    messageContent = 0;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchLEDoff

//Function to send all updated status values from arduino to the webpage
void statusUpdate(uint8_t num) {

    //Valve C
    if(currValveStatusNumC == 0)
    {
        valveColorC = "red";
        valveTubePropsC = "175px solid #00ADEF";
        valveStatusC = "Closed";
    } //end if
    else if(currValveStatusNumC == 1)
    {
        valveColorC = "green";
        valveTubePropsC = "350px solid #00ADEF"; 
        valveStatusC = "Open";
    } //end else if

    //Valve D
    if(currValveStatusNumD == 0)
    {
        valveColorD = "red";
        valveTubePropsD = "175px solid #00ADEF";
        valveStatusD = "Closed";
    } //end if
    else if(currValveStatusNumD == 1)
    {
        valveColorD = "green";
        valveTubePropsD = "350px solid #00ADEF"; 
        valveStatusD = "Open";
    } //end else if

    //Valve E
    if(currValveStatusNumE == 0)
    {
        valveColorE = "red";
        valveTubePropsE = "175px solid #00ADEF";
        valveStatusE = "Closed";
    } //end if
    else if(currValveStatusNumE == 1)
    {
        valveColorE = "green";
        valveTubePropsE = "350px solid #00ADEF"; 
        valveStatusE = "Open";
    } //end else if

    String test = ""; 
    test += currNumRefresh;
    test += ",";
    test += currMicroC;
    test += ",";
    test += currMicroD;
    test += ",";
    test += currMicroE;
    test += ",";
    test += currPressureC;
    test += ","; 
    test += currPressureD;
    test += ",";
    test += currPressureE;
    test += ","; 
    test += valveColorC;
    test += ",";
    test += valveTubePropsC;
    test += ",";
    test += valveStatusC;
    test += ","; 
    test += valveColorD;
    test += ",";
    test += valveTubePropsD;
    test += ",";
    test += valveStatusD;
    test += ","; 
    test += valveColorE;
    test += ",";
    test += valveTubePropsE;
    test += ",";
    test += valveStatusE;
    test += ",";
    test += currFluid;

    test.toCharArray(statusbuf, 256);
    webSocket.sendTXT(num, statusbuf, strlen(statusbuf));
} //end function statusUpdate

// Current POWER status
bool POWERStatus;

// Current LED status
bool LEDStatus;

// Commands sent through Web Socket
const char LEDON[] = "ledon";
const char LEDOFF[] = "ledoff";

const char teensyPOWERON[] = "teensyPOWERon";
const char teensyPOWEROFF[] = "teensyPOWERoff";

const char pumpPOWERON[] = "pumpPOWERon";
const char pumpPOWEROFF[] = "pumpPOWERoff";

const char teensyLEDON[] = "teensyLEDon";
const char teensyLEDOFF[] = "teensyLEDoff";

const char statusIdentifier[] = "Update Status";


//Websocket Event Function
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
  //if(mySerial)
   //mySerial.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
  switch(type) {
    case WStype_DISCONNECTED:
      //if(mySerial)
          //mySerial.printf("[%u] Disconnected!\r\n", num);
      break;
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);
        //if(mySerial)
          //mySerial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);

      } //end case CONNECTED
      break;
    case WStype_TEXT:
      //if(mySerial)
        //mySerial.printf("[%u] get Text: %s\r\n", num, payload);

      if(strcmp(teensyPOWERON,  (const char *)payload) == 0) {
          switchPOWERon();
      } //end if

      else if(strcmp(teensyPOWEROFF,  (const char *)payload) == 0) {
          switchPOWERoff();
      } //end else if

      else if(strcmp(pumpPOWERON,  (const char *)payload) == 0) {
          pumpPOWERon();
      } //end else if

      else if(strcmp(pumpPOWEROFF,  (const char *)payload) == 0) {
          pumpPOWERoff();
      } //end else if

      else if(strcmp(teensyLEDON,  (const char *)payload) == 0) {
          switchLEDon();
      } //end else if

      else if(strcmp(teensyLEDOFF,  (const char *)payload) == 0) {
          switchLEDoff();
      } //end else if

      else if(strcmp(statusIdentifier, (const char *)payload) == 0) {
          statusUpdate(num);
      } //end else if
      else 
      {
        if(mySerial)
            mySerial.println("Unknown command");
      } //end else

      // send data to all connected clients
      webSocket.broadcastTXT(payload, length);
      break;
    case WStype_BIN:
      if(mySerial)
        mySerial.printf("[%u] get binary length: %u\r\n", num, length);
      hexdump(payload, length);

      // echo data back to browser
      webSocket.sendBIN(num, payload, length);
      break;
    default:
      if(mySerial)
        mySerial.printf("Invalid WStype [%d]\r\n", type);
      break;
  } //end switch
} //end function webSocketEvent

我还包含了jQuery和这个量表库:https://github.com/Mikhus/canv-gauge

以下是SPIFFS服务器上的完整文件列表:

list of files

由于帖子大小限制,我没有包含HTML / CSS / JS;如果这有用,请告诉我,我会在回复中发布该代码。

1 个答案:

答案 0 :(得分:2)

好吧所以我似乎通过使用修改后的库,压缩我的代码以及完全删除jQuery来解决这个问题。我偶尔会遇到错误,但这些似乎是不可避免的,一切都在大部分时间都有效。