Projekt

Obecné

Profil

Stáhnout (3.82 KB) Statistiky
| Větev: | Tag: | Revize:
1 681d1a97 Jakub Hejman
#ifndef CURVEDATASERVER_H
2
#define CURVEDATASERVER_H
3
4
#include <QObject>
5
#include <QTcpServer>
6
#include <QTcpSocket>
7 0cda8e8d Oto Šťáva
#include <map>
8
#include <mutex>
9 6d9543aa Jakub Hejman
#include <thread>
10 f06d5ae1 Jakub Hejman
11 313ff1dc Oto Šťáva
12
/**
13
 * Manages communication with clients who can connect to the server in order to receive real-time data about the current
14
 * exercise. The served data may be used e.g. for external visualization. A reference implementation of such a client is
15
 * the deltarobot-vr Unity application.
16
 */
17 681d1a97 Jakub Hejman
class CurveDataServer : QObject
18
{
19
    Q_OBJECT
20
21
public:
22 313ff1dc Oto Šťáva
23
    /**
24
     * Holds information about a client, its Qt socket, data buffer etc.
25
     */
26 0cda8e8d Oto Šťáva
    struct Client {
27 6d9543aa Jakub Hejman
        static const size_t BUF_SIZE = 4096;
28 0cda8e8d Oto Šťáva
        static const size_t MESSAGE_ID_SIZE = 2;
29
30 313ff1dc Oto Šťáva
        QTcpSocket* socket;                 ///< Communication socket
31
        std::map<uint64_t, uint64_t> ping;  ///< Key: ping ID;  Value: ping timestamp (msec);
32
        uint64_t latency;                   ///< Current latency
33
        uint64_t lastPong;                  ///< Timestamp of the last pong
34 0cda8e8d Oto Šťáva
35 313ff1dc Oto Šťáva
        char buf[BUF_SIZE];                 ///< Message buffer
36
        size_t bufUsed = 0;                 ///< Number of bytes used up in the message buffer
37 0cda8e8d Oto Šťáva
38 313ff1dc Oto Šťáva
        bool magic = false;                 ///< Whether the client has sent the protocol magic
39
        bool version = false;               ///< Whether the client has sent the protocol version
40
        bool initialized = false;           ///< Whether the client has successfully initialized its communication (by sending its magic and version)
41 6d9543aa Jakub Hejman
42 0cda8e8d Oto Šťáva
        Client(QTcpSocket* socket);
43
    };
44
45
    explicit CurveDataServer();
46
    ~CurveDataServer();
47
48 313ff1dc Oto Šťáva
    /** Sends the current actuator position. */
49 e6053a29 Oto Šťáva
    void sendActuatorPosition(float x, float y, float z);
50 313ff1dc Oto Šťáva
51
    /** Sends the actual direction the actuator is moving in. */
52 f06d5ae1 Jakub Hejman
    void sendActualDirection(float x, float y, float z);
53 313ff1dc Oto Šťáva
54
    /** Sends the direction the actuator *should* be moving in, in order to draw the curve. */
55 f06d5ae1 Jakub Hejman
    void sendTargetDirection(float x, float y, float z);
56 313ff1dc Oto Šťáva
57
    /** Stores and sends the specified curve. */
58 705930ed Jakub Hejman
    void sendNewCurve(QList<QVector4D> &points);
59 313ff1dc Oto Šťáva
60
    /** Stores and sends the specified curve. */
61 705930ed Jakub Hejman
    void sendNewCurve(QList<QVector3D> &points);
62 313ff1dc Oto Šťáva
63
    /** Sends the currently stored curve. This is used for newly connected clients. */
64 6d9543aa Jakub Hejman
    void sendCurve(Client &client);
65
66 313ff1dc Oto Šťáva
    /** Sends ping messages to the clients, checks whether any clients have timed out, and disconnects any that have. */
67
    void processPings();
68 681d1a97 Jakub Hejman
69
public slots:
70
    void onNewConnection();
71
    void onSocketStateChanged(QAbstractSocket::SocketState socketState);
72
    void onReadyRead();
73
74
private:
75 313ff1dc Oto Šťáva
    /** Gets the client that is connected via the specified socket. */
76 0cda8e8d Oto Šťáva
    QList<Client>::iterator clientOf(QTcpSocket *socket);
77
78
    void handleMessage(Client& client, uint16_t messageId, void* content);
79 6d9543aa Jakub Hejman
    void handleProtocolMagic(Client& client, char* content);
80
    void handleVersion(Client& client, uint8_t content);
81
    void handlePong(Client& client, uint64_t* content);
82
    void handleEOT(Client& client, char* content);
83
84
    void removeSocket(QTcpSocket *socket);
85
    void terminateConnection(Client& client, std::string&& reason);
86
    void sendPing(Client& client);
87 0cda8e8d Oto Šťáva
88 e60ade62 Jakub Hejman
    void sendPreamble(QTcpSocket *socket);
89
    void sendProtocolMagic(QTcpSocket *socket);
90
    void sendVersion(QTcpSocket *socket);
91 0cda8e8d Oto Šťáva
    void sendEot(QTcpSocket *socket, std::string&& message);
92 681d1a97 Jakub Hejman
93 6d9543aa Jakub Hejman
    void sendMessageToAllConnected(QByteArray &message);
94
95
    void threadFunction();
96
97 681d1a97 Jakub Hejman
    QTcpServer _server;
98 6d9543aa Jakub Hejman
    std::thread _pingThread;
99
100 313ff1dc Oto Šťáva
    /**
101
     * A flag that can be switched to `false` when the application should end, in order to gracefully stop the ping
102
     * thread.
103
     */
104 6d9543aa Jakub Hejman
    volatile bool _threadIsRunning = true;
105 0cda8e8d Oto Šťáva
106
    std::recursive_mutex _socketsLock;
107
    QList<Client> _sockets;
108 6d9543aa Jakub Hejman
109
    std::recursive_mutex _currentCurveLock;
110
    QList<QVector3D> _currentCurve;
111 681d1a97 Jakub Hejman
};
112
113
#endif // CURVEDATASERVER_H