gpt4 book ai didi

c - 使用delay()时Arduino Socket.io显示已断开连接

转载 作者:行者123 更新时间:2023-11-30 16:09:46 24 4
gpt4 key购买 nike

我是 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: %s\n", payload);
break;
case sIOtype_EVENT:
USE_SERIAL.printf("[IOc] get event: %s\n", payload);
break;
case sIOtype_ACK:
USE_SERIAL.printf("[IOc] get ack: %u\n", length);
hexdump(payload, length);
break;
case sIOtype_ERROR:
USE_SERIAL.printf("[IOc] get error: %u\n", length);
hexdump(payload, length);
break;
case sIOtype_BINARY_EVENT:
USE_SERIAL.printf("[IOc] get binary: %u\n", length);
hexdump(payload, length);
break;
case sIOtype_BINARY_ACK:
USE_SERIAL.printf("[IOc] get binary ack: %u\n", 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 %s\n", 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 毫秒左右。所以任何延迟都是不合理的。如果您需要更多处理,请尝试熟悉事件处理。最简单的方法是将标志声明为 bool 值,并将计时器声明为计算时间间隔。当计时器启动时,它会将标志设置为 true,您可以处理函数。

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

希望对您有所帮助。

关于c - 使用delay()时Arduino Socket.io显示已断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59032840/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com