ESP32 Arduino无法连接NodeJS SocketIO WebSocket问题求助
ESP32无法连接Node.js Socket.IO服务器问题
问题背景
ESP32已成功连接WiFi,能通过HTTP读取服务器页面内容,但无法建立Socket.IO WebSocket连接,串口反复输出断开信息。开发环境为CLion + PlatformIO Arduino。
ESP32原代码
#include <Arduino.h> #include <WebSocketsClient.h> #include <HTTPClient.h> WebSocketsClient websocket; boolean connected = false; // 原代码此处缺少分号 void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: Serial.printf("[WSc] Disconnected!\n"); connected = false; break; case WStype_CONNECTED: digitalWrite(MESSAGE_LED_PIN, HIGH); // 原代码未定义MESSAGE_LED_PIN Serial.printf("[WSc] Connected to url: %s\n", payload); connected = true; break; // 原代码缺少break } } // 原代码缺少函数闭合的} void setup() { Serial.begin(115200); WiFi.begin("SSID", "PASSW"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("Connesso al WiFi"); Serial.println(WiFi.localIP()); inviaRichiestaHTTP(); // 未提供该函数代码 websocket.begin("192.168.1.16",3000,"/socket.io/?EIO=4"); websocket.onEvent(webSocketEvent); } void loop() { websocket.loop(); }
串口输出
.... Connesso al WiFi 192.168.1.170 [HTTP] Codice di stato: 200 <h1>Hello world</h1> [WSc] Disconnected! [WSc] Disconnected! [WSc] Disconnected!
Node.js原服务器代码
const ip = require("ip"); var app = require('express')(); var server = require('http').createServer(app); var io = require('socket.io')(server); //pass a http.Server instance var port = process.env.PORT || 80; app.get('/', function (req, res) { //check sender ip var senderip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; console.log('sender ip: '+senderip); res.send('<h1>Hello world</h1>'); }); io.on('connection', function (socket) { console.log('Client connected'); socket.on('message', function (data) { console.log('Message received: ', data); }); socket.on('disconnect', function () { console.log('Client disconnected'); }); }); server.listen(port);
问题排查与解决方法
1. 端口不匹配
Node.js服务器监听80端口(port = process.env.PORT || 80),但ESP32连接的是3000端口,端口不一致直接导致连接失败。
- 修正:要么把Node.js服务器端口改为3000,要么将ESP32的连接端口改为80,确保两端端口一致。
2. Socket.IO协议兼容性
WebSocketsClient是标准WebSocket客户端库,而Socket.IO是基于WebSocket的自定义协议,包含额外的握手和数据包格式,标准WebSocket客户端无法直接兼容。
- 替换为ESP32专用的Socket.IO客户端库,比如PlatformIO中的
SocketIoClient库,直接搜索安装即可使用。
3. ESP32代码语法错误
原代码存在3处语法错误,会导致运行异常:
boolean connected = false末尾缺少分号;webSocketEvent函数未闭合(缺少});MESSAGE_LED_PIN未定义,需提前用#define MESSAGE_LED_PIN 2声明引脚。
修正后的示例代码
ESP32代码(使用SocketIoClient库)
#include <Arduino.h> #include <WiFi.h> #include <SocketIoClient.h> #define MESSAGE_LED_PIN 2 // 定义LED引脚 SocketIoClient socketIO; void setup() { Serial.begin(115200); pinMode(MESSAGE_LED_PIN, OUTPUT); WiFi.begin("SSID", "PASSW"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nConnesso al WiFi"); Serial.println(WiFi.localIP()); // 连接Socket.IO服务器,端口与服务器保持一致 socketIO.begin("192.168.1.16", 80); // 监听连接事件 socketIO.on("connect", []() { Serial.println("[SocketIO] 已成功连接"); digitalWrite(MESSAGE_LED_PIN, HIGH); }); // 监听断开事件 socketIO.on("disconnect", []() { Serial.println("[SocketIO] 连接已断开"); digitalWrite(MESSAGE_LED_PIN, LOW); }); } void loop() { socketIO.loop(); }
Node.js服务器代码(明确端口并添加启动日志)
const app = require('express')(); const server = require('http').createServer(app); const io = require('socket.io')(server); const port = 80; // 明确使用80端口 app.get('/', function (req, res) { const senderip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; console.log('sender ip: ' + senderip); res.send('<h1>Hello world</h1>'); }); io.on('connection', function (socket) { console.log('Client connected'); socket.on('message', function (data) { console.log('Message received: ', data); }); socket.on('disconnect', function () { console.log('Client disconnected'); }); }); server.listen(port, () => { console.log(`服务器运行在端口 ${port}`); });
内容的提问来源于stack exchange,提问作者Ivan Cisternino
相关产品推荐
相关产品推荐

