我正在尝试使用NodeMCU模块构建一个简单的演示:
当提交正确的WiFi凭据时,这非常好用。但是,如果提供了错误的WiFi密码,ESP8266WebServer会断开与客户端的连接。
演示中的Web服务器可以处理3个请求并为每个请求返回响应。
我明确在状态和网络中引入了15秒的延迟,以测试连接断开是否不是由于超时引起的。
这是我测试的方式(在客户端上使用Postman):
while
方法中的connectToWiFi()
循环正在运行。大概5-6秒后,我在Postman中收到“无法获得任何响应”消息。同时,我在15秒后(如预期)在日志中看到了网络呼叫的最终状态有效负载。如果我再次使用错误的凭据再次致电Networks,则现在仅在1-2秒后出现“无法获得任何响应”消息。我注意到的是,如果删除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();
}