You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32 CAM同时使用esp_http_server与WebServer库出现间歇性404错误求助

解决方案:ESP32 WebServer与esp_http_server冲突导致的间歇性404错误

问题核心

Arduino标准WebServer库与ESP-IDF原生esp_http_server(startCameraServer()依赖该库)默认都监听TCP 80端口,两者的请求处理逻辑会互相抢占,导致部分请求被其中一方拦截后无法匹配对应路由,最终返回404错误。

方案1:统一使用esp_http_server实现所有功能(推荐)

放弃Arduino的WebServer,基于esp_http_server搭建完整服务,同时保留摄像头流功能:

  • 保留startCameraServer()调用,它会自动注册摄像头流相关路由(如/stream)。
  • 手动为esp_http_server添加自定义路由,处理LED PWM、RSSI查询及双向通信接口:
    // 自定义请求处理函数示例:返回RSSI值
    esp_err_t get_rssi_handler(httpd_req_t *req) {
        int rssi = WiFi.RSSI();
        char response[32];
        snprintf(response, sizeof(response), "{\"rssi\": %d}", rssi);
        httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN);
        return ESP_OK;
    }
    
    // 在启动服务器后注册路由
    void setup() {
        // 初始化WiFi、摄像头...
        httpd_handle_t camera_server = startCameraServer();
        
        // 注册RSSI查询路由
        httpd_uri_t rssi_uri = {
            .uri       = "/api/rssi",
            .method    = HTTP_GET,
            .handler   = get_rssi_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(camera_server, &rssi_uri);
        
        // 同理注册LED PWM控制等其他路由
    }
    

方案2:改用Arduino生态摄像头库,统一使用WebServer

使用支持WebServer的Arduino摄像头封装库替代startCameraServer(),避免引入esp_http_server:

  • 移除startCameraServer()调用,在WebServer中注册摄像头流路由:
    #include "esp_camera.h"
    WebServer server(80);
    
    void handleStream() {
        server.setContentLength(CONTENT_LENGTH_UNKNOWN);
        server.send(200, "multipart/x-mixed-replace; boundary=frame");
        while (true) {
            camera_fb_t *fb = esp_camera_fb_get();
            if (!fb) continue;
            
            server.sendContent("--frame\r\n");
            server.sendContent("Content-Type: image/jpeg\r\n\r\n");
            server.sendContent((const char *)fb->buf, fb->len);
            server.sendContent("\r\n");
            
            esp_camera_fb_return(fb);
            if (!server.client().connected()) break;
        }
    }
    
    void setup() {
        // 初始化WiFi、摄像头...
        server.on("/stream", handleStream);
        server.on("/api/rssi", [](){
            int rssi = WiFi.RSSI();
            server.send(200, "application/json", "{\"rssi\": " + String(rssi) + "}");
        });
        // 注册其他LED PWM控制路由...
        server.begin();
    }
    

方案3:让两个服务器监听不同端口(不推荐)

如果必须同时使用两个库,修改其中一个服务器的监听端口:

  • 例如将ArduinoWebServer改为监听8080端口:WebServer server(8080);
  • 网页端需对应调整请求地址:摄像头流访问http://<esp32-ip>/stream,Ajax请求访问http://<esp32-ip>:8080/api/rssi
  • 注意:双服务器会占用更多ESP32资源,且增加代码维护复杂度,仅作为临时 workaround。

调试建议

  • 开启ESP32串口日志(设置Serial.begin(115200)),查看两个服务器的请求处理日志,确认请求被哪个模块拦截。
  • 检查路由定义,避免两个服务器注册相同路径的路由。

内容的提问来源于stack exchange,提问作者Ray25

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:06:17