const int donationBoundary = 25;
// websocket constants
- const QUrl websocketUrl = QUrl(QStringLiteral("ws://7e6egbawekbkxzkv4244pqeqgoo4axko2imgjbedwnn6s5yb6b7oliqd.onion/ws"));
+ const QVector<QUrl> websocketUrls = {
+ QUrl(QStringLiteral("ws://7e6egbawekbkxzkv4244pqeqgoo4axko2imgjbedwnn6s5yb6b7oliqd.onion/ws")),
+ QUrl(QStringLiteral("ws://an5ecwgzyujqe7jverkp42d22zhvjes2mrhvol6tpqcgfkzwseqrafqd.onion/ws"))
+ };
// website constants
const QString websiteUrl = "https://featherwallet.org";
WebsocketClient::WebsocketClient(QObject *parent)
: QObject(parent)
{
+ connect(&webSocket, &QWebSocket::stateChanged, this, &WebsocketClient::onStateChanged);
connect(&webSocket, &QWebSocket::connected, this, &WebsocketClient::onConnected);
connect(&webSocket, &QWebSocket::disconnected, this, &WebsocketClient::onDisconnected);
connect(&webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &WebsocketClient::onError);
});
m_pingTimer.setInterval(30 * 1000);
m_pingTimer.start();
+
+ connect(&m_connectionTimeout, &QTimer::timeout, this, &WebsocketClient::onConnectionTimeout);
+
+ m_websocketUrlIndex = QRandomGenerator::global()->bounded(constants::websocketUrls.length());
+ this->nextWebsocketUrl();
}
void WebsocketClient::sendMsg(const QByteArray &data) {
void WebsocketClient::onDisconnected() {
qDebug() << "WebSocket disconnected";
+ this->nextWebsocketUrl();
QTimer::singleShot(1000, [this]{this->start();});
}
+void WebsocketClient::onStateChanged(QAbstractSocket::SocketState state) {
+ if (state == QAbstractSocket::ConnectingState) {
+ m_connectionTimeout.start(m_timeout*1000);
+ }
+ else if (state == QAbstractSocket::ConnectedState) {
+ m_connectionTimeout.stop();
+ }
+}
+
void WebsocketClient::onError(QAbstractSocket::SocketError error) {
qCritical() << "WebSocket error: " << error;
auto state = webSocket.state();
}
}
+void WebsocketClient::nextWebsocketUrl() {
+ m_url = constants::websocketUrls[m_websocketUrlIndex];
+ m_websocketUrlIndex = (m_websocketUrlIndex+1)%constants::websocketUrls.length();
+}
+
+void WebsocketClient::onConnectionTimeout() {
+ qWarning() << "Websocket connection timeout";
+ m_timeout = std::min(m_timeout + 5, 60);
+ this->onDisconnected();
+}
+
void WebsocketClient::onbinaryMessageReceived(const QByteArray &message) {
- qDebug() << "WebSocket received:" << message;
+// qDebug() << "WebSocket received:" << message;
if (!Utils::validateJSON(message)) {
qCritical() << "Could not interpret WebSocket message as JSON";
private slots:
void onConnected();
void onDisconnected();
+ void onStateChanged(QAbstractSocket::SocketState state);
void onbinaryMessageReceived(const QByteArray &message);
void onError(QAbstractSocket::SocketError error);
+ void nextWebsocketUrl();
+ void onConnectionTimeout();
private:
- QUrl m_url = constants::websocketUrl;
+ QUrl m_url;
QTimer m_pingTimer;
+ QTimer m_connectionTimeout;
+ int m_timeout = 10;
+ int m_websocketUrlIndex = 0;
};
#endif //FEATHER_WEBSOCKETCLIENT_H