ESP32 Websocket服务器仅接收首个数据包问题求助
ESP32 Websocket服务器重复接收图像数据失败排查
我的项目基于ESP32与Websocket实现:带摄像头的ESP32作为服务器将图像数据转发至移动端,移动端可正常接收并在网页显示图像;随后移动端需将数据包转发至另一台作为Websocket服务器的ESP32,由其在TFT屏显示图像。
当前遇到的问题:
- 仅能接收首张图像,之后移动端抛出Websocket连接失败错误,但移动端与ESP32均未主动关闭连接
- 调整定时器/延迟后,移动端可转发更多数据包,但ESP32无接收反馈(串口监视器无相关输出)
我已查阅资料,了解readBlocking与readNonBlocking的区别,但所用的ArduinoWebsockets库仅支持readBlocking;网上同类项目(同ESP32、同库)可重复接收Websocket数据,且代码与我的相似,暂未定位问题。
请协助排查Websocket协议使用是否有误,或代码中是否存在问题。
附Arduino IDE编写的代码:
#include <SPIFFS.h> #include <SPI.h> #include <ArduinoWebsockets.h> #include <WiFi.h> #include <TJpg_Decoder.h> #include <TFT_eSPI.h> const char* ssid = "ssid_here"; const char* password = "password_here"; const char* imageFileName = "/camimage.jpeg"; using namespace websockets; WebsocketsServer server; WebsocketsClient client; TFT_eSPI tft = TFT_eSPI(); // 调用自定义库 boolean SDInited = false; bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap) { // 当图像超出屏幕底部时停止解码 if ( y >= tft.height() ) return 0; // 该函数会自动在TFT边界处裁剪图像块进行渲染 tft.pushImage(x, y, w, h, bitmap); // 返回1继续解码下一个块 return 1; } void setup() { // 初始化代码,仅运行一次 Serial.begin(115200); while(!Serial); delay(1000); if(!SPIFFS.begin(true)){ Serial.println("SPIFFS初始化失败!"); while(1) yield(); }else{ SDInited = true; Serial.println("SPIFFS初始化成功"); } Serial.println("开始连接WiFi"); WiFi.begin(ssid, password); // 初始化WiFi连接 delay(500); for(int i = 0; i < 15 && WiFi.status() != WL_CONNECTED; i++) { Serial.print("."); delay(1000); } IPAddress IP = WiFi.localIP(); // 定义IP变量用于检查 Serial.print("IP地址 : "); Serial.println(IP); // 打印IP地址用于Websocket连接 Serial.println("初始化TFT屏幕"); delay(1000); tft.begin(); // 初始化TFT tft.setRotation(3); // 横屏模式 tft.fillScreen(random(0xFFFF)); // 屏幕填充随机颜色 delay(1000); Serial.flush(); // 清空串口缓冲区 delay(1000); tft.setSwapBytes(true); // 交换颜色字节提升图像清晰度 TJpgDec.setJpgScale(1); // 不改变缩放比例 TJpgDec.setCallback(tft_output); // 设置解码器的渲染回调函数 server.listen(80); // WebSocket监听端口80 // 检查服务器是否可用,并在串口监视器输出结果 Serial.print("服务器是否可用? -> "); if(server.available()!=0){ Serial.println("是"); } else { Serial.println("否"); } } void loop() { // 主循环代码,重复运行 Serial.println("进入循环..."); if(SDInited){ Serial.println("SPIFFS已初始化"); WebsocketsClient client = server.accept(); // 接受连接 if(client.available()){ WebsocketsMessage msg = client.readBlocking(); // 读取接收到的数据到msg boolean isSaved = fileWrite(imageFileName, msg); // 将msg和文件名传入fileWrite函数保存 if(isSaved){ Serial.println(msg.data()); // 在串口监视器打印数据用于检查 uint32_t t = millis(); Serial.println(t); // 在串口监视器打印时间戳用于检查 // 获取接收到的图像的宽高像素值 uint16_t w = 0, h = 0; TJpgDec.getFsJpgSize(&w, &h, imageFileName); // 注意文件名前需加"/" Serial.print("宽度 = "); Serial.print(w); Serial.print(", 高度 = "); Serial.println(h); TJpgDec.drawFsJpg(0, 0, imageFileName); // 在TFT屏幕绘制图像 } } } } boolean fileWrite(String name, WebsocketsMessage content){ SPIFFS.remove("/camimage.jpeg"); File file = SPIFFS.open(name.c_str(), "w"); if(!file){ String errorMsg = "无法打开文件"; Serial.println(errorMsg); return false; }else{ file.write((const uint8_t*) content.c_str(), content.length()); file.close(); return true; } }
内容的提问来源于stack exchange,提问作者T Franklin
相关产品推荐
相关产品推荐

