2019-04-23 02:31:49 +03:00
|
|
|
#include "EXClient.h"
|
|
|
|
|
#include "EXMgr.h"
|
|
|
|
|
#include "Util.h"
|
|
|
|
|
#include <QtNetwork>
|
2019-04-23 12:36:51 +03:00
|
|
|
|
2019-04-28 00:09:48 +03:00
|
|
|
|
2019-04-27 12:38:50 +03:00
|
|
|
EXClient::EXClient(EXMgr *mgr, qint64 id, const QString &host, quint16 tport, quint16 sport)
|
2019-04-30 19:21:47 +03:00
|
|
|
: RPC::Connection(mgr->rpcMethods(), id, nullptr), host(host), tport(tport), sport(sport), mgr(mgr)
|
2019-04-23 02:31:49 +03:00
|
|
|
{
|
|
|
|
|
Debug() << __FUNCTION__ << " host:" << host << " t:" << tport << " s:" << sport;
|
2019-04-26 08:47:46 +03:00
|
|
|
_thread.setObjectName(QString("%1 %2").arg("EXClient").arg(host));
|
2019-04-28 00:09:48 +03:00
|
|
|
setObjectName(host);
|
2019-04-23 02:31:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXClient::~EXClient()
|
|
|
|
|
{
|
2019-04-28 11:59:14 +03:00
|
|
|
Debug() << __FUNCTION__ << " " << objectName();
|
2019-04-28 10:27:17 +03:00
|
|
|
stop(); ///< need to be sure to call this here rather than rely on ThreadObjectMixin, as by the time it runs, we lost our vtable
|
2019-04-23 02:31:49 +03:00
|
|
|
}
|
|
|
|
|
|
2019-04-23 21:51:53 +03:00
|
|
|
/// this should only be called from our thread, because it accesses socket which should only be touched from thread
|
2019-04-28 01:54:54 +03:00
|
|
|
QString EXClient::prettyName(bool dontTouchSocket) const
|
2019-04-23 12:36:51 +03:00
|
|
|
{
|
2019-04-26 08:47:46 +03:00
|
|
|
if (_thread.isRunning() && QThread::currentThread() != &_thread) {
|
|
|
|
|
Warning() << __PRETTY_FUNCTION__ << " called from another thread! FIXME!";
|
|
|
|
|
dontTouchSocket = true;
|
|
|
|
|
}
|
2019-04-30 19:21:47 +03:00
|
|
|
return RPC::Connection::prettyName(dontTouchSocket);
|
2019-04-23 12:36:51 +03:00
|
|
|
}
|
|
|
|
|
|
2019-04-23 18:49:36 +03:00
|
|
|
bool EXClient::isGood() const
|
|
|
|
|
{
|
2019-04-30 19:21:47 +03:00
|
|
|
return RPC::Connection::isGood() && _thread.isRunning() && info.isValid();
|
2019-04-23 18:49:36 +03:00
|
|
|
}
|
|
|
|
|
|
2019-04-23 12:36:51 +03:00
|
|
|
|
|
|
|
|
// runs in thread
|
|
|
|
|
void EXClient::on_started()
|
|
|
|
|
{
|
|
|
|
|
Debug() << "started";
|
|
|
|
|
reconnect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// runs in thread
|
|
|
|
|
void EXClient::on_finished()
|
|
|
|
|
{
|
|
|
|
|
killSocket();
|
2019-04-28 10:27:17 +03:00
|
|
|
ThreadObjectMixin::on_finished(); // calls moveToThread
|
2019-04-23 12:36:51 +03:00
|
|
|
Debug() << "finished.";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EXClient::killSocket()
|
|
|
|
|
{
|
|
|
|
|
if (socket && socket->state() != QAbstractSocket::UnconnectedState) {
|
|
|
|
|
Debug() << host << " aborting connection";
|
2019-04-30 19:21:47 +03:00
|
|
|
do_disconnect();
|
2019-04-23 12:36:51 +03:00
|
|
|
}
|
2019-04-28 14:59:01 +03:00
|
|
|
delete socket; socket = nullptr; // delete of nullptr ok
|
2019-04-23 12:36:51 +03:00
|
|
|
status = NotConnected;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EXClient::reconnect()
|
|
|
|
|
{
|
|
|
|
|
killSocket();
|
2019-04-23 18:49:36 +03:00
|
|
|
lastConnectionAttempt = Util::getTime();
|
2019-04-24 07:54:46 +03:00
|
|
|
if (sport && QSslSocket::supportsSsl()) {
|
|
|
|
|
QSslSocket *ssl;
|
|
|
|
|
socket = ssl = new QSslSocket(this);
|
|
|
|
|
auto conf = ssl->sslConfiguration();
|
|
|
|
|
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
|
|
|
|
|
ssl->setSslConfiguration(conf);
|
|
|
|
|
connect(ssl, &QSslSocket::encrypted, this, [this]{
|
2019-04-26 08:47:46 +03:00
|
|
|
Debug() << prettyName() << " connected encrypted";
|
2019-04-23 12:36:51 +03:00
|
|
|
on_connected();
|
|
|
|
|
});
|
2019-04-28 01:54:54 +03:00
|
|
|
socketConnectSignals();
|
2019-04-24 07:54:46 +03:00
|
|
|
ssl->connectToHostEncrypted(host, static_cast<quint16>(sport));
|
|
|
|
|
} else if (tport) {
|
|
|
|
|
socket = new QTcpSocket(this);
|
|
|
|
|
connect(socket, &QAbstractSocket::connected, this, [this]{
|
2019-04-26 08:47:46 +03:00
|
|
|
Debug() << prettyName() << " connected";
|
2019-04-23 12:36:51 +03:00
|
|
|
on_connected();
|
|
|
|
|
});
|
2019-04-28 01:54:54 +03:00
|
|
|
socketConnectSignals();
|
2019-04-24 07:54:46 +03:00
|
|
|
socket->connectToHost(host, static_cast<quint16>(tport));
|
2019-04-23 12:36:51 +03:00
|
|
|
} else {
|
2019-04-24 07:54:46 +03:00
|
|
|
Error() << "Cannot connect to " << host << "; no TCP port defined and SSL is disabled on this install";
|
2019-04-23 12:36:51 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-04-28 01:54:54 +03:00
|
|
|
void EXClient::do_ping()
|
2019-04-24 06:54:32 +03:00
|
|
|
{
|
2019-04-28 01:54:54 +03:00
|
|
|
emit sendRequest(mgr->newId(), "server.ping");
|
2019-04-23 16:24:18 +03:00
|
|
|
}
|
|
|
|
|
|
2019-04-23 12:36:51 +03:00
|
|
|
void EXClient::on_connected()
|
|
|
|
|
{
|
2019-04-23 21:51:53 +03:00
|
|
|
// runs in thread
|
2019-04-30 19:21:47 +03:00
|
|
|
RPC::Connection::on_connected();
|
|
|
|
|
connectedConns.push_back(
|
|
|
|
|
connect(this, &RPC::Connection::gotMessage, this,
|
|
|
|
|
[this](RPC::Connection *c, const RPC::Message &m)
|
|
|
|
|
{
|
|
|
|
|
if (this == c) emit EXClient::gotMessage(this, m); /// re-emits as EXClient * signal (different C++ signature)
|
|
|
|
|
else Error() << "this != c for gotMessage fwd! FIXME!";
|
|
|
|
|
})
|
|
|
|
|
); // connection will be auto-disconnected on socket disconnect in superclass on_disconnected impl.
|
2019-04-23 21:51:53 +03:00
|
|
|
emit newConnection(this);
|
2019-04-23 12:36:51 +03:00
|
|
|
}
|
|
|
|
|
|
2019-04-30 10:01:21 +03:00
|
|
|
void EXClient::on_disconnected()
|
|
|
|
|
{
|
2019-04-30 19:21:47 +03:00
|
|
|
RPC::Connection::on_disconnected();
|
2019-04-30 10:01:21 +03:00
|
|
|
emit lostConnection(this); /// re-emits as EXClient * signal (different method in C++)
|
|
|
|
|
}
|