summaryrefslogtreecommitdiff
path: root/src/client.cc
blob: 94f4f6753da96f525f53167d60c4267c06754802 (plain)
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
#include "client.h"

#include <cstdint>

#include <QtNetwork/QTcpSocket>
#include <QtCore/QTimer>

Client::Client(QObject *parent)
	: QObject(parent)
{
	socket = new QTcpSocket(this);
#if QT_VERSION > QT_VERSION_CHECK(5, 15, 0)
	connect(socket, &QTcpSocket::errorOccurred,
#else
	connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
#endif
	        this, &Client::errorOccurred);
	connect(socket, &QTcpSocket::connected,
	        this, &Client::connected);
	connect(socket, &QTcpSocket::disconnected,
	        this, &Client::disconnected);

	timer = new QTimer(this);
	timer->setSingleShot(true);
	connect(timer, &QTimer::timeout, this, &Client::timeout);
}

bool Client::connectToHost(const QString& host)
{
	this->host = host;
	retryConnect();
	return true;
}

bool Client::writeData(const QString& title, const QByteArray& data)
{
	if(socket->state() != QAbstractSocket::ConnectedState)
	{
		return false;
	}

	auto title_data = title.toUtf8();
	std::uint32_t title_size = title_data.size();
	std::uint32_t data_size = data.size();

	// firt write size of the entire payload (without the payload size)
	std::uint32_t payload_size = data_size + title_size + sizeof(std::uint32_t);
	socket->write((char*)&payload_size, sizeof(std::uint32_t));

	// then write title size and title
	socket->write((char*)&title_size, sizeof(std::uint32_t));
	socket->write(title_data);

	// finally write the rest of the payload
	socket->write(data);

	return socket->waitForBytesWritten(100); // wait at most 100ms
}

void Client::errorOccurred(QAbstractSocket::SocketError socketError)
{
	if(socketError == QAbstractSocket::NetworkError ||
	   socketError == QAbstractSocket::ConnectionRefusedError)
	{
		if(retries > 0)
		{
			timer->setInterval(interval * 1000);
			retries--;
		}
		else
		{
			timer->setInterval(interval_long * 1000);
		}
		timer->start();
	}
}

void Client::connected()
{
	emit isConnected();
}

void Client::disconnected()
{
	emit isDisconnected();
	retryConnect();
}

void Client::timeout()
{
	retryConnect();
}

void Client::retryConnect()
{
	socket->connectToHost(host, 10024);
}