C语言 Arduino Socket.io 在使用 delay() 时显示断开连接



我是Arduino的新手,面临一个问题。我正在Arduino中实现套接字ESP8266。当我不使用delay()或不使用someFunction()时,它可以按预期工作。 一旦我使用延迟或进行一些处理,我就会断开一个服务器套接字的连接。

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ArduinoJson.h>
#include <WebSocketsClient.h>
#include <SocketIOclient.h>
#include <Hash.h>
ESP8266WiFiMulti WiFiMulti;
SocketIOclient socketIO;
#define USE_SERIAL Serial1
void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
switch(type) {
case sIOtype_DISCONNECT:
USE_SERIAL.printf("[IOc] Disconnected!n");
break;
case sIOtype_CONNECT:
USE_SERIAL.printf("[IOc] Connected to url: %sn", payload);
break;
case sIOtype_EVENT:
USE_SERIAL.printf("[IOc] get event: %sn", payload);
break;
case sIOtype_ACK:
USE_SERIAL.printf("[IOc] get ack: %un", length);
hexdump(payload, length);
break;
case sIOtype_ERROR:
USE_SERIAL.printf("[IOc] get error: %un", length);
hexdump(payload, length);
break;
case sIOtype_BINARY_EVENT:
USE_SERIAL.printf("[IOc] get binary: %un", length);
hexdump(payload, length);
break;
case sIOtype_BINARY_ACK:
USE_SERIAL.printf("[IOc] get binary ack: %un", length);
hexdump(payload, length);
break;
}
}
void setup() {
// USE_SERIAL.begin(921600);
USE_SERIAL.begin(115200);
//Serial.setDebugOutput(true);
USE_SERIAL.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...n", t);
USE_SERIAL.flush();
delay(1000);
}
// disable AP
if(WiFi.getMode() & WIFI_AP) {
WiFi.softAPdisconnect(true);
}
WiFiMulti.addAP("SSID", "passpasspass");
//WiFi.disconnect();
while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
String ip = WiFi.localIP().toString();
USE_SERIAL.printf("[SETUP] WiFi Connected %sn", ip.c_str());
// server address, port and URL
socketIO.begin("10.11.100.100", 8880);
// event handler
socketIO.onEvent(socketIOEvent);
}
unsigned long messageTimestamp = 0;
void loop() {
socketIO.loop();
uint64_t now = millis();
if(now - messageTimestamp > 2000) {
messageTimestamp = now;
// creat JSON message for Socket.IO (event)
DynamicJsonDocument doc(1024);
JsonArray array = doc.to<JsonArray>();
// add evnet name
// Hint: socket.on('event_name', ....
array.add("event_name");
// add payload (parameters) for the event
JsonObject param1 = array.createNestedObject();
param1["now"] = now;
// JSON to String (serializion)
String output;
serializeJson(doc, output);
// Send event        
socketIO.sendEVENT(output);
// Print JSON for debugging
USE_SERIAL.println(output);
}
//NEED TO DO SOME PROCESSIONG
delay(2000);
someFuntion();
}

void someFunction(){
//some processing that consume the time
}

您在服务器端超时。

当你做delay(10000)esp8266只是挂在某个循环上(作为延迟实现( - 任何其他代码这次都不会执行。因此,当服务器没有获取任何数据时,它会断开客户端的连接。

解决方案(简单的方法(是每次要发送数据时建立新连接。在伪代码中,它将如下所示:

void loop(){
connectToServer();
sendData();
Disconnect();
delay(1000);
SomeFunction();
}

那么它应该可以工作。

更复杂的方法是熟悉事件和回调的概念,并摆脱delay()函数。或者尝试使用esp_rtos_sdk女巫是异步任务概念RTOS框架。

玩得愉快!

编辑:

刷新代码后,我能够告诉它更多关于它的信息,所以我正在编辑上一篇文章。

使其工作的最快方法(部分(是删除delay(2000)语句 - 因为此If()语句正在处理 2 秒间隔发送的消息。正如我所看到的,你可能也不想把这个void someFunction()放在这个if()声明上。这将使"一些处理"在 2 秒间隔内进行。

socketIO.loop()正在处理维护与服务器的连接并将事件发送到服务器,因此必须尽可能快地调用它。如果是delay,您会收到套接字超时和断开连接。

void loop()函数必须尽可能短,以保持连接。可能是 500 毫秒左右 - 关于你的实验。因此,任何延迟都是不合理的。如果需要更多处理,请尝试熟悉事件处理。最简单的方法是将标志声明为布尔值,并将计时器声明为时间间隔。当计时器午餐时,它将标志设置为 true,您可以处理函数。

ESP(或其他嵌入式微处理器(上的Websockets对于初学者来说很难,因为它们依赖于时间。您需要使用较短的处理循环或使用一些异步方法。

我希望,我能帮忙。

最新更新