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

能否在ESP32 AsyncWebServer声明后修改/重置端口?

ESP32 AsyncWebServer 动态配置端口实现方案

方案1:先读NVS再初始化服务器(推荐)

由于全局变量初始化早于setup(),无法在全局阶段读取NVS,所以改用指针延迟初始化服务器,步骤如下:

  • 全局声明服务器指针,而非直接创建实例:
    AsyncWebServer* server = nullptr;
    
  • 在setup()中先初始化NVS,读取存储的端口(无存储值时用默认80);
  • 用读取到的端口创建服务器实例,配置路由后启动;
  • 用户修改端口并保存到NVS后,重启ESP32生效(AsyncWebServer无官方热改端口API,重启是最稳妥的方式)。

完整代码示例

#include <AsyncWebServer.h>
#include <Preferences.h>

Preferences preferences;
AsyncWebServer* server = nullptr;
const uint16_t DEFAULT_PORT = 80;

void setup() {
  Serial.begin(115200);

  // 初始化NVS存储区(命名为webserver)
  if (!preferences.begin("webserver", false)) {
    Serial.println("NVS初始化失败,将使用默认端口");
  }

  // 读取端口,无存储值则用默认80
  uint16_t port = preferences.getUShort("server_port", DEFAULT_PORT);
  Serial.printf("当前使用端口:%d\n", port);

  // 创建服务器实例
  server = new AsyncWebServer(port);

  // 配置端口设置页面路由
  server->on("/config", HTTP_GET, [port](AsyncWebServerRequest *request){
    String html = "<form method='POST' action='/save-port'>";
    html += "<input type='number' name='port' min='1' max='65535' value='" + String(port) + "'>";
    html += "<button type='submit'>保存端口</button></form>";
    request->send(200, "text/html", html);
  });

  // 保存端口路由
  server->on("/save-port", HTTP_POST, [](AsyncWebServerRequest *request){
    if (request->hasParam("port", true)) {
      uint16_t new_port = request->getParam("port", true)->value().toInt();
      if (new_port >= 1 && new_port <= 65535) {
        preferences.putUShort("server_port", new_port);
        request->send(200, "text/plain", "端口已保存,设备即将重启...");
        delay(1000); // 等待响应发送完成
        ESP.restart();
      } else {
        request->send(400, "text/plain", "无效端口,需在1-65535之间");
      }
    } else {
      request->send(400, "text/plain", "未提交端口参数");
    }
  });

  // 启动服务器
  server->begin();
}

void loop() {
  // 你的业务循环代码
}

方案2:动态修改端口(不推荐)

AsyncWebServer没有官方支持热修改端口的接口,强行修改需要先停止服务器、销毁旧实例、重新创建新端口的实例并重新配置所有路由,过程中容易出现连接中断、资源泄漏问题。如果一定要尝试,核心逻辑如下:

  1. 当用户提交新端口后,调用server->end();停止旧服务器;
  2. 销毁旧实例:delete server;;
  3. 用新端口创建新实例,重新配置所有路由后启动。

这种方式稳定性远不如重启,仅适合特殊场景使用。

关键注意事项

  • NVS初始化失败时要兜底用默认端口,避免设备无法启动;
  • 配置页面必须做端口合法性校验(1-65535),防止无效值写入;
  • 修改端口后重启设备是最可靠的生效方式,避免潜在的连接异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:20:19