Introduce ping for keeping the connection alive
This commit is contained in:
parent
1ca3119995
commit
accb6ec166
@ -79,7 +79,6 @@ public:
|
||||
TcpSocketServer *tcpSocketServerTunnelProxy() const;
|
||||
WebSocketServer *webSocketServerTunnelProxy() const;
|
||||
|
||||
|
||||
MonitorServer *monitorServer() const;
|
||||
LogEngine *logEngine() const;
|
||||
|
||||
|
||||
@ -57,6 +57,13 @@ TunnelProxyHandler::TunnelProxyHandler(QObject *parent) : JsonHandler(parent)
|
||||
returns.insert("tunnelProxyError", JsonTypes::tunnelProxyErrorRef());
|
||||
setReturns("DisconnectClient", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("Ping", "In order to keep a connection alive when no client is connected, this Ping method can be used. The sent timestamp will be returned as sent in the response for speed measuements on the client side.");
|
||||
params.insert("timestamp", JsonTypes::basicTypeToString(JsonTypes::UInt));
|
||||
setParams("Ping", params);
|
||||
returns.insert("timestamp", JsonTypes::basicTypeToString(JsonTypes::UInt));
|
||||
setReturns("Ping", returns);
|
||||
|
||||
|
||||
// Client
|
||||
params.clear(); returns.clear();
|
||||
@ -123,6 +130,14 @@ JsonReply *TunnelProxyHandler::DisconnectClient(const QVariantMap ¶ms, Trans
|
||||
return createReply("DisconnectClient", response);
|
||||
}
|
||||
|
||||
JsonReply *TunnelProxyHandler::Ping(const QVariantMap ¶ms, TransportClient *transportClient)
|
||||
{
|
||||
qCDebug(dcJsonRpc()) << name() << "ping received" << params << transportClient;
|
||||
QVariantMap response;
|
||||
response.insert("timestamp", params.value("timestamp"));
|
||||
return createReply("Ping", response);
|
||||
}
|
||||
|
||||
JsonReply *TunnelProxyHandler::RegisterClient(const QVariantMap ¶ms, TransportClient *transportClient)
|
||||
{
|
||||
qCDebug(dcJsonRpc()) << name() << "register client" << params << transportClient;
|
||||
|
||||
@ -48,6 +48,7 @@ public:
|
||||
// Server
|
||||
Q_INVOKABLE JsonReply *RegisterServer(const QVariantMap ¶ms, TransportClient *transportClient);
|
||||
Q_INVOKABLE JsonReply *DisconnectClient(const QVariantMap ¶ms, TransportClient *transportClient);
|
||||
Q_INVOKABLE JsonReply *Ping(const QVariantMap ¶ms, TransportClient *transportClient);
|
||||
|
||||
// Client
|
||||
Q_INVOKABLE JsonReply *RegisterClient(const QVariantMap ¶ms, TransportClient *transportClient);
|
||||
|
||||
@ -106,6 +106,18 @@ JsonReply *JsonRpcClient::callDisconnectClient(quint16 socketAddress)
|
||||
return reply;
|
||||
}
|
||||
|
||||
JsonReply *JsonRpcClient::callPing(uint timestamp)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("timestamp", timestamp);
|
||||
|
||||
JsonReply *reply = new JsonReply(m_commandId, "TunnelProxy", "Ping", params, this);
|
||||
qCDebug(dcRemoteProxyClientJsonRpc()) << "Calling" << QString("%1.%2").arg(reply->nameSpace()).arg(reply->method());
|
||||
sendRequest(reply->requestMap(), true);
|
||||
m_replies.insert(m_commandId, reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
void JsonRpcClient::sendRequest(const QVariantMap &request, bool slipEnabled)
|
||||
{
|
||||
QByteArray data = QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact) + '\n';
|
||||
|
||||
@ -57,6 +57,7 @@ public:
|
||||
JsonReply *callRegisterServer(const QUuid &serverUuid, const QString &serverName);
|
||||
JsonReply *callRegisterClient(const QUuid &clientUuid, const QString &clientName, const QUuid &serverUuid);
|
||||
JsonReply *callDisconnectClient(quint16 socketAddress);
|
||||
JsonReply *callPing(uint timestamp);
|
||||
|
||||
private:
|
||||
ProxyConnection *m_connection = nullptr;
|
||||
|
||||
@ -42,7 +42,7 @@ TunnelProxySocketServer::TunnelProxySocketServer(const QUuid &serverUuid, const
|
||||
m_serverUuid(serverUuid),
|
||||
m_serverName(serverName)
|
||||
{
|
||||
setupReconnectTimer();
|
||||
setupTimers();
|
||||
}
|
||||
|
||||
TunnelProxySocketServer::TunnelProxySocketServer(const QUuid &serverUuid, const QString &serverName, ConnectionType connectionType, QObject *parent) :
|
||||
@ -51,7 +51,7 @@ TunnelProxySocketServer::TunnelProxySocketServer(const QUuid &serverUuid, const
|
||||
m_serverName(serverName),
|
||||
m_connectionType(connectionType)
|
||||
{
|
||||
setupReconnectTimer();
|
||||
setupTimers();
|
||||
}
|
||||
|
||||
TunnelProxySocketServer::~TunnelProxySocketServer()
|
||||
@ -189,6 +189,9 @@ void TunnelProxySocketServer::onConnectionDataAvailable(const QByteArray &data)
|
||||
{
|
||||
qCDebug(dcTunnelProxySocketServerTraffic()) << "Data received" << qUtf8Printable(data);
|
||||
|
||||
// We recived data, let's reset the keep alive timer
|
||||
m_keepAliveTimer.start();
|
||||
|
||||
if (m_state != StateRunning) {
|
||||
m_jsonClient->processData(data);
|
||||
m_dataBuffer.clear();
|
||||
@ -345,13 +348,13 @@ void TunnelProxySocketServer::requestSocketDisconnect(quint16 socketAddress)
|
||||
|
||||
JsonReply *reply = m_jsonClient->callDisconnectClient(socketAddress);
|
||||
connect(reply, &JsonReply::finished, this, [=](){
|
||||
reply->deleteLater();
|
||||
// TODO: handle errors
|
||||
qCDebug(dcTunnelProxySocketServer()) << "Request to disconnect client finished" << reply->response();
|
||||
reply->deleteLater();
|
||||
// TODO: handle errors
|
||||
qCDebug(dcTunnelProxySocketServer()) << "Request to disconnect client finished" << reply->response();
|
||||
});
|
||||
}
|
||||
|
||||
void TunnelProxySocketServer::setupReconnectTimer()
|
||||
void TunnelProxySocketServer::setupTimers()
|
||||
{
|
||||
m_reconnectTimer.setInterval(5000);
|
||||
m_reconnectTimer.setSingleShot(false);
|
||||
@ -367,6 +370,24 @@ void TunnelProxySocketServer::setupReconnectTimer()
|
||||
startServer(m_serverUrl);
|
||||
}
|
||||
});
|
||||
|
||||
m_keepAliveTimer.setInterval(30000);
|
||||
m_keepAliveTimer.setSingleShot(false);
|
||||
connect(&m_keepAliveTimer, &QTimer::timeout, this, [this](){
|
||||
if (m_state == StateRunning) {
|
||||
qCDebug(dcTunnelProxySocketServer()) << "Ping the proxy server to keep the connection alive";
|
||||
quint64 requestTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||
JsonReply *reply = m_jsonClient->callPing(QDateTime::currentMSecsSinceEpoch() / 1000);
|
||||
connect(reply, &JsonReply::finished, this, [=](){
|
||||
quint64 pingDuration = QDateTime::currentMSecsSinceEpoch() - requestTimestamp;
|
||||
reply->deleteLater();
|
||||
qCDebug(dcTunnelProxySocketServer()) << "Ping response received" << reply->response() << "Duration:" << pingDuration << "ms";
|
||||
});
|
||||
} else {
|
||||
// The server is not running any more
|
||||
m_keepAliveTimer.stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void TunnelProxySocketServer::setState(State state)
|
||||
@ -383,6 +404,7 @@ void TunnelProxySocketServer::setState(State state)
|
||||
if (m_state == StateDisconnected && m_enabled) {
|
||||
qCDebug(dcTunnelProxySocketServer()) << "Starting reconnect timer...";
|
||||
m_reconnectTimer.start();
|
||||
m_keepAliveTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,6 +416,13 @@ void TunnelProxySocketServer::setRunning(bool running)
|
||||
qCDebug(dcTunnelProxySocketServer()) << "The TunnelProxy server" << (running ? "is now up and running. Listening for remote clients" : "not running any more.");
|
||||
m_running = running;
|
||||
emit runningChanged(m_running);
|
||||
|
||||
if (m_running) {
|
||||
qCDebug(dcTunnelProxySocketServer()) << "Starting the keep alive timer";
|
||||
m_keepAliveTimer.start();
|
||||
} else {
|
||||
m_keepAliveTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelProxySocketServer::setError(QAbstractSocket::SocketError error)
|
||||
|
||||
@ -149,6 +149,7 @@ private:
|
||||
State m_state = StateDisconnected;
|
||||
|
||||
QTimer m_reconnectTimer;
|
||||
QTimer m_keepAliveTimer;
|
||||
bool m_enabled = false;
|
||||
|
||||
ProxyConnection *m_connection = nullptr;
|
||||
@ -159,7 +160,7 @@ private:
|
||||
QByteArray m_dataBuffer;
|
||||
|
||||
void requestSocketDisconnect(quint16 socketAddress);
|
||||
void setupReconnectTimer();
|
||||
void setupTimers();
|
||||
|
||||
void setState(State state);
|
||||
void setRunning(bool running);
|
||||
|
||||
@ -4,8 +4,8 @@ QT -= gui
|
||||
# Define versions
|
||||
SERVER_NAME=nymea-remoteproxy
|
||||
API_VERSION_MAJOR=0
|
||||
API_VERSION_MINOR=4
|
||||
SERVER_VERSION=0.2.0
|
||||
API_VERSION_MINOR=5
|
||||
SERVER_VERSION=0.2.1
|
||||
|
||||
DEFINES += SERVER_NAME_STRING=\\\"$${SERVER_NAME}\\\" \
|
||||
SERVER_VERSION_STRING=\\\"$${SERVER_VERSION}\\\" \
|
||||
|
||||
Reference in New Issue
Block a user