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

问题描述 投票:0回答:1

我是Arduino新手,面临一个问题。我正在为ESP8266在Arduino中实现套接字。当我不使用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
}
c socket.io arduino esp8266 arduino-esp8266
1个回答
0
投票

您正在服务器端超时。

[制作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(或其他嵌入式微处理器)上的Websocket对于初学者来说比较困难,因为它们与时间有关。您需要缩短处理周期或使用一些异步方法。

我希望能有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.