ESP32作为WebSocket服务器,ESP8266客户端连接失败求助
ESP32 WebSocket服务器与ESP8266客户端连接失败问题排查及解决方案
问题场景
ESP32作为WebSocket服务器,ESP8266作为客户端,同时支持手机网页控制所有设备。目前手机网页可正常连接ESP32并控制,但ESP8266客户端无法建立WebSocket连接。
常见故障排查点
- 网络一致性:确认ESP32与ESP8266连接至同一WiFi网络,ESP8266代码中填写的ESP32 IP必须为ESP32实际本地IP(可从ESP32串口输出获取)。
- AP隔离限制:检查WiFi路由器是否开启AP隔离功能,该功能会阻止同一网络内设备间通信,需关闭。
- 库版本兼容性:ESP32需安装
AsyncWebServer和AsyncWebSocket库,ESP8266需安装WebSocketClient库,确保库版本适配对应芯片。 - 路径匹配:服务器注册的WebSocket路径(如
/ws)必须与客户端连接路径完全一致,无拼写错误。 - 端口占用:确认ESP32的80端口未被其他服务占用,路由器未限制该端口的设备间通信。
可用运行脚本
ESP32 WebSocket服务器代码
#include <WiFi.h> #include <AsyncTCP.h> #include <ESPAsyncWebServer.h> #include <AsyncWebSocket.h> const char* ssid = "你的WiFi名称"; const char* password = "你的WiFi密码"; AsyncWebServer server(80); AsyncWebSocket ws("/ws"); void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { if(type == WS_EVT_CONNECT) { Serial.printf("WebSocket客户端[%u]已连接\n", client->id()); client->text("已连接至ESP32 WebSocket服务器"); } else if(type == WS_EVT_DISCONNECT) { Serial.printf("WebSocket客户端[%u]已断开\n", client->id()); } else if(type == WS_EVT_DATA) { AwsFrameInfo *info = (AwsFrameInfo*)arg; String msg = ""; if(info->final && info->index == 0 && info->len == len) { if(info->opcode == WS_TEXT) { for(size_t i=0; i<len; i++) { msg += (char)data[i]; } } Serial.printf("收到消息: %s\n", msg.c_str()); // 转发消息至所有客户端(手机网页+ESP8266) ws.textAll(msg); } } } void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("连接WiFi中..."); } Serial.println("WiFi连接成功"); Serial.print("ESP32服务器IP: "); Serial.println(WiFi.localIP()); ws.onEvent(onWsEvent); server.addHandler(&ws); // 提供网页控制界面 server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", R"rawliteral( <!DOCTYPE HTML> <html> <head> <title>设备控制中心</title> <script> var ws; function initWs() { ws = new WebSocket('ws://' + window.location.host + '/ws'); ws.onmessage = function(e) { document.getElementById('log').innerHTML += e.data + '<br>'; }; } function sendCmd(cmd) { if(ws.readyState === WebSocket.OPEN) { ws.send(cmd); } } </script> </head> <body onload="initWs()"> <h1>智能设备控制</h1> <div> <button onclick="sendCmd('ESP32_ON')">开启ESP32负载</button> <button onclick="sendCmd('ESP32_OFF')">关闭ESP32负载</button> </div> <div> <button onclick="sendCmd('ESP8266_ON')">开启ESP8266负载</button> <button onclick="sendCmd('ESP8266_OFF')">关闭ESP8266负载</button> </div> <h3>消息日志</h3> <div id="log" style="height:200px; overflow-y:auto; border:1px solid #ccc;"></div> </body> </html> )rawliteral"); }); server.begin(); } void loop() { ws.cleanupClients(); delay(10); }
ESP8266 WebSocket客户端代码
#include <ESP8266WiFi.h> #include <WebSocketClient.h> const char* ssid = "你的WiFi名称"; const char* password = "你的WiFi密码"; const char* ws_server_ip = "192.168.1.100"; // 替换为ESP32实际IP const uint16_t ws_server_port = 80; const char* ws_path = "/ws"; WebSocketClient ws; WiFiClient client; void setup() { pinMode(D4, OUTPUT); // 示例:控制D4引脚的LED Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("连接WiFi中..."); } Serial.println("WiFi连接成功"); connectWsServer(); } void connectWsServer() { if (ws.connect(client, ws_server_ip, ws_server_port, ws_path)) { Serial.println("WebSocket服务器连接成功"); ws.send("ESP8266客户端已上线"); } else { Serial.println("WebSocket服务器连接失败"); } } void loop() { if (ws.connected()) { String recvMsg; if (ws.getMessage(recvMsg)) { Serial.printf("收到服务器指令: %s\n", recvMsg.c_str()); // 执行对应操作 if (recvMsg == "ESP8266_ON") { digitalWrite(D4, HIGH); Serial.println("ESP8266负载已开启"); } else if (recvMsg == "ESP8266_OFF") { digitalWrite(D4, LOW); Serial.println("ESP8266负载已关闭"); } } } else { Serial.println("尝试重新连接WebSocket服务器..."); connectWsServer(); delay(5000); } delay(10); }
使用说明
- 替换代码中的WiFi名称、密码及ESP32 IP地址。
- 为ESP32安装
AsyncWebServer、AsyncTCP、AsyncWebSocket库;为ESP8266安装WebSocketClient库。 - 上传代码后,通过手机浏览器访问ESP32的IP地址即可控制所有设备,ESP8266会自动连接服务器并响应指令。
内容的提问来源于stack exchange,提问作者AlexB
相关产品推荐
相关产品推荐

