使用错误的密码在NodeMCU上设置WiFi会断开ESP8266WebServer连接

时间:2019-03-27 15:13:29

标签: http webserver wifi esp8266 nodemcu

我正在尝试使用NodeMCU模块构建一个简单的演示:

  1. NodeMCU打开AP并设置Web服务器
  2. 客户端连接到此AP,将有效负载发送到Web服务器以在模块上设置WiFI,并在连接成功后接收响应。

当提交正确的WiFi凭据时,这非常好用。但是,如果提供了错误的WiFi密码,ESP8266WebServer会断开与客户端的连接。

演示中的Web服务器可以处理3个请求并为每个请求返回响应。

  1. Web服务器的根目录-只是对其进行ping操作以确保它可访问。
  2. 状态-返回WiFi连接状态有效负载
  3. 网络-接受WiFi凭据,设置WiFi并返回状态有效载荷

我明确在状态和网络中引入了15秒的延迟,以测试连接断开是否不是由于超时引起的。

这是我测试的方式(在客户端上使用Postman):

  1. 上传设置了擦除WiFi设置标记的草图。
  2. 将客户端连接到AP并ping Web服务器的根,以确保其正常工作
  3. 呼叫状态几次。每次延迟15秒后都会返回响应
  4. 使用错误的凭据致电网络。我在日志中看到while方法中的connectToWiFi()循环正在运行。大概5-6秒后,我在Postman中收到“无法获得任何响应”消息。同时,我在15秒后(如预期)在日志中看到了网络呼叫的最终状态有效负载。如果我再次使用错误的凭据再次致电Networks,则现在仅在1-2秒后出现“无法获得任何响应”消息。
  5. 再次致电状态。现在,它也开始在客户端失败,而在服务器端15秒后成功生成有效负载。
  6. 立即使用正确的凭据致电网络。客户端仍然没有收到响应消息,但是服务器的代码成功运行。
  7. 此后,调用Status或Networks(具有正确的凭据)端点将开始返回有效的HTTP OK 200响应。

我注意到的是,如果删除WiFi.begin(ssid.c_str(), password.c_str());行,则永远不会收到“无响应”消息。因此,以某种方式向其提供错误的密码会弄乱响应。

我错过了什么吗?在任何情况下如何获得正确的答复?到目前为止,我唯一的解决方法是调用Networks端点,而不等待响应。然后,开始轮询状态端点,直到收到所需的响应。但是,这种解决方案看起来不太好。

这是我的草图:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "ESP8266WiFiType.h"
#include <ArduinoJson.h>

#define MESSAGE_MAX_LEN 1024

ESP8266WebServer server(80);
String ssid = "";
String password = "";
static byte mac[6]; 

void configureServer()
{
    server.on("/", []() {
        //String responseBody;
        Serial.println("Running root");

        StaticJsonBuffer<MESSAGE_MAX_LEN> jsonBuffer;
        JsonObject &root = jsonBuffer.createObject();
        root["status"] = "OK";

        String rootpayload;
        root.prettyPrintTo(rootpayload);
        Serial.print("rootpayload:");
        Serial.println(rootpayload);

        return server.send(200, "application/json", rootpayload);
    });

    server.on("/networks", []() {
        Serial.println("Running /networks");
        if (server.hasArg("ssid") && server.hasArg("pass")) {
            Serial.print("got ssid:");
            Serial.println(server.arg("ssid"));
            Serial.print("got pass:");
            Serial.println(server.arg("pass"));

            ssid = server.arg("ssid");
            password = server.arg("pass");

            connectToWiFi();

            StaticJsonBuffer<MESSAGE_MAX_LEN> jsonBuffer;
            JsonObject &root = jsonBuffer.createObject();

            JsonObject &payload = jsonBuffer.createObject();
            root["payload"] = payload;
            bool connected_status = (WiFi.status() == WL_CONNECTED);
            payload["connected"] = connected_status;
            payload["localip"] = WiFi.localIP().toString();

            String networkspayload;
            root.prettyPrintTo(networkspayload);
            Serial.println("networkspayload:");
            Serial.println(networkspayload);

            server.send(200, "application/json", networkspayload);
        }
    });


    server.on("/status", []() {
        String responseBody;
        delay(15000);
        bool connected_status = (WiFi.status() == WL_CONNECTED);
        Serial.print("wifi.status = ");
        Serial.println(WiFi.status());

        StaticJsonBuffer<MESSAGE_MAX_LEN> jsonBuffer;
        JsonObject &root = jsonBuffer.createObject();

        JsonObject &payload = jsonBuffer.createObject();
        payload["network_ssid"] = WiFi.SSID();
        payload["connected"] = connected_status;
        payload["localip"] = WiFi.localIP().toString();

        JsonArray &devicespayload = jsonBuffer.createArray();

        root["payload"] = payload;

        String statuspayload;
        root.prettyPrintTo(statuspayload);
        Serial.print("statuspayload:");
        Serial.println(statuspayload);
        return server.send(200, "application/json", statuspayload);
    });
}


void connectToWiFi()
{
    Serial.println();
    Serial.println("Connecting to the router...");
    WiFi.begin(ssid.c_str(), password.c_str());
    int t = 0;
    int timeout = 15000;
    while (WiFi.status() != WL_CONNECTED && t < timeout) {  //Wait for the connection to the WiFi network 
        delay(100);
        t += 100;
        Serial.print(".");
    }
    while ( t < timeout) { 
        delay(100);
        t += 100;
        Serial.print(".");
    }
}

String getMacAddress()
{
    String mac = WiFi.macAddress();
    mac.replace(":", "");
    mac.toLowerCase();
    return mac;
}

void openAP()
{
  Serial.println("Opening AP...");
  WiFi.mode(WIFI_AP_STA);
  boolean result = WiFi.softAP("Test AP");
  Serial.print("AP opened: ");
  Serial.println(result);
}

// the setup function runs once when you press reset or power the board
void setup() {
    Serial.begin(115200);
    Serial.println("Serial successfully inited.");

    configureServer();
    server.begin();
    openAP();

    WiFi.macAddress(mac);
    Serial.print("MAC: ");
    Serial.print(WiFi.macAddress());
    Serial.println();
    Serial.println("Server started");
    Serial.print("SSID: ");
    Serial.println(WiFi.SSID());
    Serial.print("Connected to wifi: ");
    Serial.println(WiFi.status() == WL_CONNECTED);
    Serial.print("Local IP: ");
    Serial.println(WiFi.localIP().toString());
}

// the loop function runs over and over again until power down or reset
void loop() {
  server.handleClient();
}

0 个答案:

没有答案