1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#ifndef CLIENT_H_
#define CLIENT_H_
#include <QtCore>
#include <QSslError>
#include <QAbstractSocket>
#include "../../shared/networkmessage.h"
class QSslSocket;
struct ClientLogin
{
bool accept;
QString name;
QString host;
QString ip;
};
typedef int ClientId;
class Client : public QObject
{
Q_OBJECT
private:
static ClientId _clientIdCounter;
QSslSocket *_socket;
int _authed; // 0 = challenge sent, awaiting reply 1 = challenge ok, client challenge replied, awaiting login, 2 = ESTABLISHED
QString _name;
QString _host;
QString _ip;
QByteArray _challenge;
qint64 _pingTimeout;
NetworkMessage _toClient, _fromClient;
int _timerIdAuthTimeout;
ClientId _id; // this client's unique id
// If this client should be projected to from another client, the other client's id is set here. 0 otherwise.
// This is not currently used and it is questionable if this makes sense, as it might just be confusing if
// several groups students watch different other students.
// Also, visualizing such a situation in the GUI in a meaningful way would be hard.
ClientId _desiredProjectionSource;
// This boolean tells whether this client is currently the VNC broadcast source. This
// version only allows "one to all others" setups
bool _isProjectionSource;
ClientId _currentProjectionSource;
QString _vncRwPass, _vncRoPass;
int _vncPort;
bool _activeVncClient;
void handleMsg();
void disconnect();
protected:
void timerEvent(QTimerEvent* event);
public:
explicit Client(QSslSocket* socket);
~Client();
void requestThumb(const int width, const int height);
void sendMessage(NetworkMessage& message);
//void acceptData();
const inline bool isAuthed() const { return _authed == 2; }
const inline QString& name() const { return _name; }
const inline QString& host() const { return _host; }
const inline QString& ip() const { return _ip; }
// The computer ID (used eg. for saving the frame positions) is currently the IP, but this is an extra method for easier modification later on
const inline QString& computerId() const { return _ip; }
const inline ClientId id() const { return _id; }
inline const QString& vncRwPass() const { return _vncRwPass; }
inline const QString& vncRoPass() const { return _vncRoPass; }
inline const int vncPort() const { return _vncPort; }
inline const bool isActiveVncClient() const { return _activeVncClient; }
inline const bool isActiveVncServer() const { return _vncPort > 0; }
inline const ClientId desiredProjectionSource() const { return _desiredProjectionSource; }
inline void setDesiredProjectionSource(ClientId source) { _desiredProjectionSource = source; }
inline const bool isProjectionSource() const { return _isProjectionSource; }
inline void setProjectionSource(bool enable) { _isProjectionSource = enable; }
inline const ClientId currentProjectionSource() const { return _currentProjectionSource; }
inline void setCurrentProjectionSource(ClientId source) { _currentProjectionSource = source; }
void startVncServer();
void stopVncServer();
signals:
void authenticating(Client* client, ClientLogin* request);
void authenticated(Client* client);
void thumbUpdated(Client* client, const QPixmap& thumb);
void vncServerStateChange(Client* client);
void vncClientStateChange(Client* client);
private slots:
void onSslErrors(const QList<QSslError> & errors); // triggered for errors that occur during SSL negotiation
void onDataArrival(); // triggered if data is available for reading
void onClosed(); // triggered if the socket is closed
void onError(QAbstractSocket::SocketError errcode); // triggered if an error occurs on the socket
};
#endif /* CLIENT_H_ */
|