首页 > 解决方案 > ESP32 和 Kotlin 服务器之间的套接字延迟不一致

问题描述

语境:

为了测试,服务器每秒以交替模式发送FF0000|FF00000000FF|0000FF(作为字符串)60 次。这个测试效果很好,因为如果颜色以每秒 60 次的速度更新,LED 应该看起来是紫色的。如果系统表现不佳,那么我将看到各个颜色。

客户端 Github 存储库服务器 Github 存储库以获取更多上下文。

问题:

我非常清楚地看到交替的蓝色、红色和紫色。这告诉我某处存在性能问题,但也有短暂的时刻按预期执行。

我的发现:

我一直在记录读取客户端上每条消息所需的时间:

std::string SocketManager::getNextCommand()
{
    unsigned long start = micros();

    // TODO: Flush isn't working
    // flush(): fail on fd 56, errno: 11, "No more processes"
    // client.flush();

    // We need to read in our next command; wait until command is available.
    String message;
    while (client.connected() && message.length() == 0)
    {
        message = client.readStringUntil('\n');
    }

    unsigned long end = micros();
    Serial.print("Time: ");
    Serial.println(end - start);

    return message.c_str();
}

打印出来的时间通常很好,但我每秒会收到大约 10 次的周期性峰值。我在这里向 Pastebin 添加了一个日志。

当我第一次看到这个时,我认为客户端缓冲区已经饱和了。然后我将服务器上的消息速率降低到每秒 2 次,但我仍然看到消息时间的显着变化。那个日志在这里

每当服务器发送消息以验证它是否以正确的速率写入时,我都会打印出系统时间。每秒更新 2 次始终会产生 500 毫秒的间隙,因此我认为排除服务器是合理的。这表明问题出在传输时间或 ESP32(考虑到服务器以指定的时间间隔发布)。

当套接字不活动时,两个设备之间的 ping 为 5-10 毫秒,但当套接字处于活动状态时为 50-400+……即使我没有来回发送任何消息!哎呀-即使我完全注释掉客户端的while循环(即它立即返回一个空字符串),它也这么高。

问题:

看来我的中心问题是套接字处于活动状态时设备之间的延迟。至少 - 套接字处于活动状态时的 ping 增加似乎在尝试读取下一个命令时延迟增加的范围内。

您认为套接字是这里的主要问题吗?如果是这样 - 为什么?

对我来说似乎很奇怪,仅仅由于套接字处于活动状态就会发生如此巨大的延迟增加……尤其是在不来回传输任何大量数据的情况下。

标签: c++socketskotlinarduinoesp32

解决方案


我基于此线程设置了性能首选项并禁用了服务器套接字连接上的 TCP 延迟。

在服务器代码中,我将 ServerSocket 性能首选项设置为 1、2、0。

val server = ServerSocket(9999)
server.setPerformancePreferences(1, 2, 0)

我还禁用了连接上的 TCP 延迟。

while (true) {
    val client = server.accept()
    println("Client connected: ${client.inetAddress.hostAddress}")

    client.soTimeout = 1000
    client.tcpNoDelay = true;

    // Run client in it's own thread.
    thread { ClientHandler(client).run() }
}

这似乎取得了巨大的进步。肯定有一些时候灯光(大部分)是紫色的。似乎延迟会随着时间的推移而降低,并且连接可能会中断,因此仍然需要进行微调。

所以 - 我认为这个问题基本上已经解决了(通过一些微调)。也就是说,我仍然会感谢任何人提供的任何进一步的意见。


推荐阅读