Browse Source

update data fifo & add connect interrupt prompt

xuqiang 4 months ago
parent
commit
01ff5a1381
4 changed files with 103 additions and 45 deletions
  1. 2 0
      include/datafifo.h
  2. 4 0
      include/mainwindow.h
  3. 57 41
      src/datafifo.cpp
  4. 40 4
      src/mainwindow.cpp

+ 2 - 0
include/datafifo.h

@@ -13,10 +13,12 @@ public:
 
     void start();
     void stop();
+    const qint64 recvTimestamp();
 
 private:
     QThread m_thread;
     bool m_isRunning;
+    qint64 m_recvTimestamp;
 
 signals:
     void updateScreen(const QJsonObject &obj);

+ 4 - 0
include/mainwindow.h

@@ -3,6 +3,8 @@
 
 #include <QMainWindow>
 #include <QStackedWidget>
+#include <QTimer>
+#include <QLabel>
 
 #define MAX_CANVAS_COUNT 12
 
@@ -22,6 +24,8 @@ protected:
 
 private:
     QStackedWidget *m_pStackedWidget;
+    QTimer m_timer;
+    QLabel *m_pErrStrLabel;
 
 public slots:
     void onUpdateScreen(const QJsonObject &obj);

+ 57 - 41
src/datafifo.cpp

@@ -5,15 +5,16 @@
 #include <QJsonObject>
 #include <QJsonArray>
 #include <QJsonDocument>
+#include <QDateTime>
 #include <QDebug>
 #include <fcntl.h>
 #include "logger.h"
-
-#define FIFO_PATH           "/tmp/netparse"
+#include "defs.h"
 
 DataFifo::DataFifo(QObject *parent)
     : QObject(parent)
     , m_isRunning(false)
+    , m_recvTimestamp(QDateTime::currentMSecsSinceEpoch())  // 初始化接收数据时间戳
 {
     connect(&m_thread, &QThread::started, this, &DataFifo::doWork);
     moveToThread(&m_thread);
@@ -31,7 +32,7 @@ void DataFifo::stop()
     m_isRunning = false;
 
     // 打开写端写一个换行,唤醒阻塞的 read
-    int fd = open(FIFO_PATH, O_WRONLY | O_NONBLOCK);
+    int fd = open(CALCULATE_FIFO_PATH, O_WRONLY | O_NONBLOCK);
     if (fd != -1) {
         write(fd, "\n", 1);
         close(fd);
@@ -41,53 +42,68 @@ void DataFifo::stop()
     m_thread.wait();
 }
 
+const qint64 DataFifo::recvTimestamp()
+{
+    return m_recvTimestamp;
+}
+
 void DataFifo::doWork()
 {
-    // 1. 创建 FIFO(如果已存在忽略错误)
-    if (mkfifo(FIFO_PATH, 0666) == -1) {
-        if (errno != EEXIST) {
-            LOG_ERROR("mkfifo error");
-            return;
+    while(m_isRunning) {
+        // 1. 创建 FIFO(如果已存在忽略错误)
+        if (mkfifo(NETPARSE_FIFO_PATH, 0666) == -1) {
+            if (errno != EEXIST) {
+                LOG_ERROR("mkfifo error");
+                return;
+            }
         }
-    }
 
-    // 2. 打开 FIFO 读端
-    int fd = open(FIFO_PATH, O_RDONLY);
-    if (fd == -1) {
-        LOG_ERROR("open fifo error");
-        return;
-    }
+        if (mkfifo(CALCULATE_FIFO_PATH, 0666) == -1) {
+            if (errno != EEXIST) {
+                LOG_ERROR("mkfifo error");
+                return;
+            }
+        }
+
+        // 2. 打开 FIFO 读端
+        int fd = open(CALCULATE_FIFO_PATH, O_RDONLY);
+        if (fd == -1) {
+            LOG_ERROR("open fifo error");
+            return;
+        }
 
-    FILE *stream = fdopen(fd, "r");
+        FILE *stream = fdopen(fd, "r");
 
-    ssize_t n;
-    char *line = NULL;
-    size_t len = 0;
+        ssize_t n;
+        char *line = NULL;
+        size_t len = 0;
 
-    // 3. 循环读取
-    while (m_isRunning) {
-        n = getline(&line, &len, stream);
-        if(n > 0) {
-            LOG_DEBUG("read size: {}, buffer size: {}, data: {}", n, len, line);
-            QByteArray byteArray(line, n);
-            QJsonParseError error;
-            QJsonDocument doc = QJsonDocument::fromJson(byteArray, &error);
-            if(error.error == QJsonParseError::NoError && doc.isObject()) {
-                QJsonObject obj = doc.object();
-                emit updateScreen(obj);
+        // 3. 循环读取
+        while (m_isRunning) {
+            n = getline(&line, &len, stream);
+            if(n > 0) {
+                m_recvTimestamp = QDateTime::currentMSecsSinceEpoch();  // 更新接收数据时间戳
+                LOG_INFO("read size: {}, buffer size: {}, data: {}", n, len, line);
+                QByteArray byteArray(line, n);
+                QJsonParseError error;
+                QJsonDocument doc = QJsonDocument::fromJson(byteArray, &error);
+                if(error.error == QJsonParseError::NoError && doc.isObject()) {
+                    QJsonObject obj = doc.object();
+                    emit updateScreen(obj);
+                } else {
+                    LOG_ERROR("data fifo: invalid json");
+                }
+            } else if (n == 0) {
+                // FIFO 写端关闭时 read 返回 0
+                LOG_INFO("writer closed. exiting.");
+                break;
             } else {
-                LOG_ERROR("data fifo: invalid json");
+                LOG_ERROR("read error");
+                break;
             }
-        } else if (n == 0) {
-            // FIFO 写端关闭时 read 返回 0
-            LOG_INFO("writer closed. exiting.");
-            break;
-        } else {
-            LOG_ERROR("read error");
-            break;
         }
+        free(line);
+        fclose(stream); // 会同时关闭文件描述符
+        // close(fd);
     }
-    free(line);
-    fclose(stream); // 会同时关闭文件描述符
-    // close(fd);
 }

+ 40 - 4
src/mainwindow.cpp

@@ -8,10 +8,12 @@
 #include "utils.h"
 #include "abstractwidget.h"
 #include <QSettings>
+#include <QDateTime>
 
 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
     , m_pStackedWidget(nullptr)
+    , m_pErrStrLabel(nullptr)
 {
     setWindowFlags(Qt::FramelessWindowHint | Qt::Window);
     init_ui();
@@ -28,6 +30,37 @@ MainWindow::MainWindow(QWidget *parent)
 
     DataFifo &dataFifo = AppContext::instance().dataFifo();
     connect(&dataFifo, &DataFifo::updateScreen, this, &MainWindow::onUpdateScreen);
+
+    connect(&m_timer, &QTimer::timeout, this, [this](){
+        DataFifo &dataFifo = AppContext::instance().dataFifo();
+        qint64 recvTimestamp = dataFifo.recvTimestamp();
+        qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
+        if((timestamp - recvTimestamp) >= 5000) {
+            emit disconnect();
+            LOG_INFO("data transfer interrupted");
+            if(!m_pErrStrLabel) {
+                QFont font;
+                font.setPixelSize(40);
+                font.setBold(true);
+                m_pErrStrLabel = new QLabel("数据传输中断!", this);
+                m_pErrStrLabel->resize(this->size());
+                m_pErrStrLabel->setFont(font);
+                m_pErrStrLabel->setAlignment(Qt::AlignCenter);
+                m_pErrStrLabel->setStyleSheet("QLabel { background-color: #FFD6D6; color: #D8000C; padding: 4px; border-radius: 4px; }");
+                m_pErrStrLabel->move((this->width() - m_pErrStrLabel->width()) / 2, (this->height() - m_pErrStrLabel->height()) / 2);
+                m_pErrStrLabel->show();
+            }
+        } else {
+            if(m_pErrStrLabel) {
+                delete m_pErrStrLabel;
+                m_pErrStrLabel = nullptr;
+            }
+        }
+
+        LOG_INFO("{} {}", timestamp, recvTimestamp);
+    });
+
+    m_timer.start(1000);
 }
 
 MainWindow::~MainWindow()
@@ -127,8 +160,8 @@ void MainWindow::setCurrentCanvas(bool isNewComfigure)
 
 void MainWindow::onUpdateScreen(const QJsonObject &obj)
 {
-    QElapsedTimer timer;
-    timer.start(); // 开始计时
+    // QElapsedTimer timer;
+    // timer.start(); // 开始计时
 
     ProjectManager &projectMgr = AppContext::instance().projectManager();
     int canvasCount = projectMgr.canvasCount();
@@ -183,8 +216,11 @@ void MainWindow::onUpdateScreen(const QJsonObject &obj)
 
     }
 
-    qint64 duration = timer.elapsed(); // 获取经过的毫秒数
-    LOG_DEBUG("update screen duration: {}ms", duration);
+    // qint64 duration = timer.elapsed(); // 获取经过的毫秒数
+
+    qint64 startTime = obj["time_arrived"].toString().toLongLong();
+    qint64 endTime = Utils::currentNanoTimestamp();
+    LOG_INFO("update screen duration: {}ns", endTime - startTime);
 }
 
 void MainWindow::onPageSwitdh(int state)