diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 99053d8..b5a53d5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -15,6 +15,7 @@ #include "turnstile.h" #include "senttxstore.h" #include "connection.h" +#include "websockets.h" using json = nlohmann::json; @@ -98,7 +99,7 @@ MainWindow::MainWindow(QWidget *parent) : } void MainWindow::createWebsocket() { - + new WSServer(8237, true, this); } void MainWindow::restoreSavedStates() { diff --git a/src/mainwindow.h b/src/mainwindow.h index 9626bd1..45ed702 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -40,6 +40,7 @@ public: void updateLabelsAutoComplete(); void setDefaultPayFrom(); + RPC* getRPC() { return rpc; } Ui::MainWindow* ui; diff --git a/src/rpc.cpp b/src/rpc.cpp index 5b5cfef..f3848ff 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -712,17 +712,17 @@ void RPC::refreshBalances() { // 1. Get the Balances getBalance([=] (json reply) { - auto balT = QString::fromStdString(reply["transparent"]).toDouble(); - auto balZ = QString::fromStdString(reply["private"]).toDouble(); - auto tot = QString::fromStdString(reply["total"]).toDouble(); + balT = QString::fromStdString(reply["transparent"]).toDouble(); + balZ = QString::fromStdString(reply["private"]).toDouble(); + balTotal = QString::fromStdString(reply["total"]).toDouble(); ui->balSheilded ->setText(Settings::getZECDisplayFormat(balZ)); ui->balTransparent->setText(Settings::getZECDisplayFormat(balT)); - ui->balTotal ->setText(Settings::getZECDisplayFormat(tot)); + ui->balTotal ->setText(Settings::getZECDisplayFormat(balTotal)); ui->balSheilded ->setToolTip(Settings::getUSDFormat(balZ)); ui->balTransparent->setToolTip(Settings::getUSDFormat(balT)); - ui->balTotal ->setToolTip(Settings::getUSDFormat(tot)); + ui->balTotal ->setToolTip(Settings::getUSDFormat(balTotal)); }); // 2. Get the UTXOs diff --git a/src/rpc.h b/src/rpc.h index 7f0c18d..4a05efe 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -71,6 +71,10 @@ public: Turnstile* getTurnstile() { return turnstile; } Connection* getConnection() { return conn; } + double balT; + double balZ; + double balTotal; + private: void refreshBalances(); diff --git a/src/websockets.cpp b/src/websockets.cpp new file mode 100644 index 0000000..2b1dad2 --- /dev/null +++ b/src/websockets.cpp @@ -0,0 +1,75 @@ + +#include "websockets.h" +#include "rpc.h" +#include "settings.h" + +WSServer::WSServer(quint16 port, bool debug, QObject *parent) : + QObject(parent), + m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Direct Connection Server"), + QWebSocketServer::NonSecureMode, this)), + m_debug(debug) +{ + m_mainWindow = (MainWindow *) parent; + if (m_pWebSocketServer->listen(QHostAddress::LocalHost, port)) { + if (m_debug) + qDebug() << "Echoserver listening on port" << port; + connect(m_pWebSocketServer, &QWebSocketServer::newConnection, + this, &WSServer::onNewConnection); + connect(m_pWebSocketServer, &QWebSocketServer::closed, this, &WSServer::closed); + } +} + +WSServer::~WSServer() +{ + qDebug() << "Closing websocket"; + m_pWebSocketServer->close(); + qDeleteAll(m_clients.begin(), m_clients.end()); +} + +void WSServer::onNewConnection() +{ + QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection(); + + connect(pSocket, &QWebSocket::textMessageReceived, this, &WSServer::processTextMessage); + connect(pSocket, &QWebSocket::binaryMessageReceived, this, &WSServer::processBinaryMessage); + connect(pSocket, &QWebSocket::disconnected, this, &WSServer::socketDisconnected); + + m_clients << pSocket; +} + +void WSServer::processTextMessage(QString message) +{ + QWebSocket *pClient = qobject_cast(sender()); + if (m_debug) + qDebug() << "Message received:" << message; + if (pClient) { + QJsonDocument json(QJsonObject { + {"saplingAddress", m_mainWindow->getRPC()->getDefaultSaplingAddress()}, + {"balance", m_mainWindow->getRPC()->balTotal}, + {"zecprice", Settings::getInstance()->getZECPrice()} + }); + + pClient->sendTextMessage(json.toJson()); + } +} + +void WSServer::processBinaryMessage(QByteArray message) +{ + QWebSocket *pClient = qobject_cast(sender()); + if (m_debug) + qDebug() << "Binary Message received:" << message; + if (pClient) { + pClient->sendBinaryMessage(message); + } +} + +void WSServer::socketDisconnected() +{ + QWebSocket *pClient = qobject_cast(sender()); + if (m_debug) + qDebug() << "socketDisconnected:" << pClient; + if (pClient) { + m_clients.removeAll(pClient); + pClient->deleteLater(); + } +} \ No newline at end of file diff --git a/src/websockets.h b/src/websockets.h new file mode 100644 index 0000000..284ac11 --- /dev/null +++ b/src/websockets.h @@ -0,0 +1,34 @@ +#ifndef WEBSOCKETS_H +#define WEBSOCKETS_H + +#include "mainwindow.h" +#include "precompiled.h" + + +QT_FORWARD_DECLARE_CLASS(QWebSocketServer) +QT_FORWARD_DECLARE_CLASS(QWebSocket) + +class WSServer : public QObject +{ + Q_OBJECT +public: + explicit WSServer(quint16 port, bool debug = false, QObject *parent = nullptr); + ~WSServer(); + +Q_SIGNALS: + void closed(); + +private Q_SLOTS: + void onNewConnection(); + void processTextMessage(QString message); + void processBinaryMessage(QByteArray message); + void socketDisconnected(); + +private: + QWebSocketServer *m_pWebSocketServer; + MainWindow *m_mainWindow; + QList m_clients; + bool m_debug; +}; + +#endif // WEBSOCKETS_H \ No newline at end of file diff --git a/zec-qt-wallet.pro b/zec-qt-wallet.pro index 361cf26..c2b698d 100644 --- a/zec-qt-wallet.pro +++ b/zec-qt-wallet.pro @@ -52,7 +52,8 @@ SOURCES += \ src/fillediconlabel.cpp \ src/addressbook.cpp \ src/logger.cpp \ - src/addresscombo.cpp + src/addresscombo.cpp \ + src/websockets.cpp HEADERS += \ src/mainwindow.h \ @@ -72,7 +73,8 @@ HEADERS += \ src/fillediconlabel.h \ src/addressbook.h \ src/logger.h \ - src/addresscombo.h + src/addresscombo.h \ + src/websockets.h FORMS += \ src/mainwindow.ui \