From 5ec00a8f103cf8fca9006902a28e5f53b500844f Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 23 Oct 2014 16:57:33 +0200 Subject: [PATCH] qethereum polling through rpc --- alethzero/MainWin.cpp | 10 ++- libqethereum/QEthereum.cpp | 131 ++++++++++++++++++++++++++++++------- libqethereum/QEthereum.h | 21 ++++-- third/MainWin.cpp | 17 +++-- 4 files changed, 138 insertions(+), 41 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index c68f79c0a..9063cd9c0 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -152,7 +152,7 @@ Main::Main(QWidget *parent) : connect(ui->webView, &QWebView::loadFinished, [=]() { -// m_ethereum->poll(); + m_qweb->poll(); }); connect(ui->webView, &QWebView::titleChanged, [=]() @@ -180,8 +180,7 @@ Main::~Main() { // Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor) // *after* the client is dead. -// m_ethereum->clientDieing(); - + m_qweb->clientDieing(); g_logPost = simpleDebugOut; writeSettings(); } @@ -1001,8 +1000,8 @@ void Main::timerEvent(QTimerEvent*) else interval += 100; -// if (m_ethereum) -// m_ethereum->poll(); + if (m_qweb) + m_qweb->poll(); for (auto const& i: m_handlers) if (ethereum()->checkWatch(i.first)) @@ -1516,7 +1515,6 @@ void Main::on_killBlockchain_triggered() ui->net->setChecked(false); web3()->stopNetwork(); ethereum()->killChain(); -// m_ethereum->setClient(ethereum()); readSettings(true); installWatches(); refreshAll(); diff --git a/libqethereum/QEthereum.cpp b/libqethereum/QEthereum.cpp index c81ec2dfb..f22f0ab6e 100644 --- a/libqethereum/QEthereum.cpp +++ b/libqethereum/QEthereum.cpp @@ -35,37 +35,121 @@ QWebThree::~QWebThree() { } -static QString toJsonRpcMessage(QString _json) +void QWebThree::poll() { - QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object(); - QJsonObject res; + if (m_watches.size() == 0) + return; - res["jsonrpc"] = "2.0"; - if (f.contains("call")) - res["method"] = f["call"]; - if (f.contains("args")) - res["params"] = f["args"]; - if (f.contains("_id")) - res["id"] = f["_id"]; + QJsonArray batch; + for (int w: m_watches) + { + QJsonObject res; + res["jsonrpc"] = "2.0"; + res["method"] = "changed"; + + QJsonArray params; + params.append(w); + res["params"] = params; + res["id"] = w; + batch.append(res); + } + + emit processData(QString::fromUtf8(QJsonDocument(batch).toJson()), "changed"); +} + +void QWebThree::clearWatches() +{ + if (m_watches.size() == 0) + return; + + QJsonArray batch; + for (int w: m_watches) + { + QJsonObject res; + res["jsonrpc"] = "2.0"; + res["method"] = "uninstallFilter"; + + QJsonArray params; + params.append(w); + res["params"] = params; + res["id"] = w; + batch.append(params); + } + m_watches.clear(); + emit processData(QString::fromUtf8(QJsonDocument(batch).toJson()), "internal"); +} + +void QWebThree::clientDieing() +{ + clearWatches(); + this->disconnect(); +} + +static QString formatInput(QJsonObject const& _object) +{ + QJsonObject res; + res["jsonrpc"] = "2.0"; + res["method"] = _object["call"]; + res["params"] = _object["args"]; + res["id"] = _object["_id"]; return QString::fromUtf8(QJsonDocument(res).toJson()); } -static QString formatResponse(QString _json) +void QWebThree::postData(QString _json) { QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object(); - QJsonObject res; - if (f.contains("id")) - res["_id"] = f["id"]; - if (f.contains("result")) - res["data"] = f["result"]; + + QString method = f["call"].toString(); + if (!method.compare("uninstallFilter")) + { + int idToRemove = -1; + if (f["args"].isArray()) + if (f["args"].toArray().size()) + idToRemove = f["args"].toArray()[0].toInt();; + m_watches.erase(std::remove(m_watches.begin(), m_watches.end(), idToRemove), m_watches.end()); + } + emit processData(formatInput(f), method); +} + +static QString formatOutput(QJsonObject const& _object) +{ + QJsonObject res; + res["_id"] = _object["id"]; + res["data"] = _object["result"]; return QString::fromUtf8(QJsonDocument(res).toJson()); } -void QWebThree::postData(QString _json) +void QWebThree::onDataProcessed(QString _json, QString _addInfo) { - emit processData(toJsonRpcMessage(_json)); + if (!_addInfo.compare("internal")) + return; + + if (!_addInfo.compare("changed")) + { + QJsonArray resultsArray = QJsonDocument::fromJson(_json.toUtf8()).array(); + for (int i = 0; i < resultsArray.size(); i++) + { + QJsonObject elem = resultsArray[i].toObject(); + if (elem.contains("result") && elem["result"].toBool() == true) + { + QJsonObject res; + res["_event"] = "messages"; + res["data"] = (int)m_watches[i]; // we can do that couse poll is synchronous + response(QString::fromUtf8(QJsonDocument(res).toJson())); + } + } + return; + } + + QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object(); + + if (!_addInfo.compare("newFilter") || !_addInfo.compare("newFilterString")) + if (f.contains("result")) + m_watches.push_back(f["result"].toInt()); + + response(formatOutput(f)); } QWebThreeConnector::QWebThreeConnector(QWebThree* _q): m_qweb(_q) @@ -79,7 +163,8 @@ QWebThreeConnector::~QWebThreeConnector() bool QWebThreeConnector::StartListening() { - connect(m_qweb, SIGNAL(processData(QString)), this, SLOT(onMessage(QString))); + connect(m_qweb, SIGNAL(processData(QString, QString)), this, SLOT(onProcessData(QString, QString))); + connect(this, SIGNAL(dataProcessed(QString, QString)), m_qweb, SLOT(onDataProcessed(QString, QString))); return true; } @@ -91,17 +176,15 @@ bool QWebThreeConnector::StopListening() bool QWebThreeConnector::SendResponse(std::string const& _response, void* _addInfo) { - Q_UNUSED(_addInfo); - emit m_qweb->send(formatResponse(QString::fromStdString(_response))); + emit dataProcessed(QString::fromStdString(_response), *(QString*)_addInfo); return true; } -void QWebThreeConnector::onMessage(QString const& _json) +void QWebThreeConnector::onProcessData(QString const& _json, QString const& _addInfo) { - OnRequest(_json.toStdString()); + OnRequest(_json.toStdString(), (void*)&_addInfo); } - // extra bits needed to link on VS #ifdef _MSC_VER diff --git a/libqethereum/QEthereum.h b/libqethereum/QEthereum.h index 95596deac..1aa0705a9 100644 --- a/libqethereum/QEthereum.h +++ b/libqethereum/QEthereum.h @@ -35,11 +35,21 @@ public: QWebThree(QObject* _p); virtual ~QWebThree(); + void poll(); + void clearWatches(); + void clientDieing(); + Q_INVOKABLE void postData(QString _json); +public slots: + void onDataProcessed(QString _json, QString _addInfo); + signals: - void processData(QString _json); - void send(QString _json); + void processData(QString _json, QString _addInfo); + void response(QString _json); + +private: + std::vector m_watches; }; class QWebThreeConnector: public QObject, public jsonrpc::AbstractServerConnector @@ -56,7 +66,10 @@ public: bool virtual SendResponse(std::string const& _response, void* _addInfo = NULL); public slots: - void onMessage(QString const& _json); + void onProcessData(QString const& _json, QString const& _addInfo); + +signals: + void dataProcessed(QString const& _json, QString const& _addInfo); private: QWebThree* m_qweb; @@ -75,7 +88,7 @@ private: " }" \ "})" \ "})()"); \ - _frame->evaluateJavaScript("navigator.qt.send.connect(function (res) {" \ + _frame->evaluateJavaScript("navigator.qt.response.connect(function (res) {" \ "navigator.qt.handlers.forEach(function (handler) {" \ " handler(res);" \ "})" \ diff --git a/third/MainWin.cpp b/third/MainWin.cpp index 73fb5bee7..82f057883 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -121,7 +121,7 @@ Main::Main(QWidget *parent) : connect(ui->webView, &QWebView::loadFinished, [=]() { -// m_ethereum->poll(); + m_qweb->poll(); }); connect(ui->webView, &QWebView::titleChanged, [=]() @@ -149,8 +149,7 @@ Main::~Main() { // Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor) // *after* the client is dead. -// m_ethereum->clientDieing(); - + m_qweb->clientDieing(); writeSettings(); } @@ -522,8 +521,8 @@ void Main::timerEvent(QTimerEvent*) else interval += 100; -// if (m_ethereum) -// m_ethereum->poll(); + if (m_qweb) + m_qweb->poll(); for (auto const& i: m_handlers) if (ethereum()->checkWatch(i.first)) @@ -542,8 +541,12 @@ void Main::ourAccountsRowsMoved() myKeys.push_back(i); } m_myKeys = myKeys; -// if (m_ethereum) -// m_ethereum->setAccounts(myKeys); + + if (m_server.get()) + { + auto list = owned().toStdList(); + m_server->setAccounts({std::begin(list), std::end(list)}); + } } void Main::on_ourAccounts_doubleClicked()