Messages work both ways for web remote.
This commit is contained in:
parent
583c8bf419
commit
d2c50c5298
|
@ -114,7 +114,6 @@ Application::Application(QObject* parent)
|
||||||
|
|
||||||
// Network Remote
|
// Network Remote
|
||||||
ClementineWebPage* web_channel = new ClementineWebPage(this);
|
ClementineWebPage* web_channel = new ClementineWebPage(this);
|
||||||
web_channel->mainFrame()->load(QUrl("http://localhost:8080/channel"));
|
|
||||||
network_remote_ = new NetworkRemote(web_channel, this);
|
network_remote_ = new NetworkRemote(web_channel, this);
|
||||||
MoveToNewThread(network_remote_);
|
MoveToNewThread(network_remote_);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QNetworkCookie>
|
#include <QNetworkCookie>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "remotecontrolmessages.pb.h"
|
||||||
#include "covers/albumcoverfetcher.h"
|
#include "covers/albumcoverfetcher.h"
|
||||||
#include "engines/enginebase.h"
|
#include "engines/enginebase.h"
|
||||||
#include "engines/gstengine.h"
|
#include "engines/gstengine.h"
|
||||||
|
@ -82,6 +83,8 @@ void RegisterMetaTypes() {
|
||||||
qRegisterMetaType<Subdirectory>("Subdirectory");
|
qRegisterMetaType<Subdirectory>("Subdirectory");
|
||||||
qRegisterMetaType<QList<QUrl> >("QList<QUrl>");
|
qRegisterMetaType<QList<QUrl> >("QList<QUrl>");
|
||||||
|
|
||||||
|
qRegisterMetaType<pb::remote::Message>("pb::remote::Message");
|
||||||
|
|
||||||
#ifdef HAVE_VK
|
#ifdef HAVE_VK
|
||||||
qRegisterMetaType<MusicOwner>("MusicOwner");
|
qRegisterMetaType<MusicOwner>("MusicOwner");
|
||||||
qRegisterMetaTypeStreamOperators<MusicOwner>("MusicOwner");
|
qRegisterMetaTypeStreamOperators<MusicOwner>("MusicOwner");
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
#include "clementinewebpage.h"
|
#include "clementinewebpage.h"
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
#include <QMetaObject>
|
||||||
|
#include <QThread>
|
||||||
#include <QWebFrame>
|
#include <QWebFrame>
|
||||||
|
|
||||||
#include "core/closure.h"
|
#include "core/closure.h"
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
#include "remotecontrolmessages.pb.h"
|
#include "remotecontrolmessages.pb.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char* kRemoteEndpoint = "http://localhost:8080/channel/remote/%1";
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
ClementineWebPage::ClementineWebPage(QObject* parent)
|
ClementineWebPage::ClementineWebPage(QObject* parent)
|
||||||
: QWebPage(parent) {
|
: QWebPage(parent) {
|
||||||
qLog(Debug) << Q_FUNC_INFO;
|
qLog(Debug) << Q_FUNC_INFO;
|
||||||
|
@ -17,8 +25,28 @@ ClementineWebPage::ClementineWebPage(QObject* parent)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClementineWebPage::Init() {
|
||||||
|
QMetaObject::invokeMethod(this, "InitOnMainThread", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClementineWebPage::InitOnMainThread() {
|
||||||
|
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||||
|
mainFrame()->load(QUrl("http://localhost:8080/channel/clementine"));
|
||||||
|
}
|
||||||
|
|
||||||
void ClementineWebPage::javaScriptConsoleMessage(
|
void ClementineWebPage::javaScriptConsoleMessage(
|
||||||
const QString& message, int, const QString&) {
|
const QString& message, int, const QString&) {
|
||||||
|
qLog(Error) << message;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClementineWebPage::javaScriptConfirm(QWebFrame*, const QString& message) {
|
||||||
|
id_ = message;
|
||||||
|
qLog(Debug) << "id:" << message;
|
||||||
|
qLog(Debug) << QString(kRemoteEndpoint).arg(message);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClementineWebPage::javaScriptAlert(QWebFrame*, const QString& message) {
|
||||||
qLog(Debug) << message;
|
qLog(Debug) << message;
|
||||||
|
|
||||||
QByteArray bytes = QByteArray::fromBase64(message.toAscii());
|
QByteArray bytes = QByteArray::fromBase64(message.toAscii());
|
||||||
|
@ -34,11 +62,8 @@ void ClementineWebPage::javaScriptConsoleMessage(
|
||||||
emit MessageReceived(msg);
|
emit MessageReceived(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClementineWebPage::javaScriptAlert(QWebFrame*, const QString& message) {
|
|
||||||
qLog(Debug) << message;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClementineWebPage::shouldInterruptJavaScript() {
|
bool ClementineWebPage::shouldInterruptJavaScript() {
|
||||||
qLog(Debug) << Q_FUNC_INFO;
|
qLog(Debug) << Q_FUNC_INFO;
|
||||||
|
// Make sure any long-running js does not get interrupted.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ class ClementineWebPage : public QWebPage {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ClementineWebPage(QObject* parent = nullptr);
|
explicit ClementineWebPage(QObject* parent = nullptr);
|
||||||
|
void Init();
|
||||||
|
const QString id() const { return id_; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool shouldInterruptJavaScript();
|
bool shouldInterruptJavaScript();
|
||||||
|
@ -15,9 +17,18 @@ class ClementineWebPage : public QWebPage {
|
||||||
void Connected();
|
void Connected();
|
||||||
void MessageReceived(const pb::remote::Message& msg);
|
void MessageReceived(const pb::remote::Message& msg);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void InitOnMainThread();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// For OOB communication for controlling the appengine channel.
|
||||||
|
virtual bool javaScriptConfirm(QWebFrame*, const QString& message);
|
||||||
|
// For generic error messages from the javascript.
|
||||||
virtual void javaScriptConsoleMessage(
|
virtual void javaScriptConsoleMessage(
|
||||||
const QString& message, int line, const QString& source);
|
const QString& message, int line, const QString& source);
|
||||||
|
// For receiving base64 proto messages; the actual remote control messages.
|
||||||
|
virtual void javaScriptAlert(QWebFrame*, const QString& message);
|
||||||
|
|
||||||
virtual void javaScriptAlert(QWebFrame*, const QString&);
|
private:
|
||||||
|
QString id_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,6 +79,7 @@ IncomingDataParser::~IncomingDataParser() {}
|
||||||
bool IncomingDataParser::close_connection() { return close_connection_; }
|
bool IncomingDataParser::close_connection() { return close_connection_; }
|
||||||
|
|
||||||
void IncomingDataParser::Parse(const pb::remote::Message& msg) {
|
void IncomingDataParser::Parse(const pb::remote::Message& msg) {
|
||||||
|
qLog(Debug) << msg.DebugString().c_str();
|
||||||
close_connection_ = false;
|
close_connection_ = false;
|
||||||
|
|
||||||
RemoteClient* client = qobject_cast<RemoteClient*>(sender());
|
RemoteClient* client = qobject_cast<RemoteClient*>(sender());
|
||||||
|
|
|
@ -75,6 +75,7 @@ void NetworkRemote::SetupServer() {
|
||||||
connect(server_ipv6_.get(), SIGNAL(newConnection()), this,
|
connect(server_ipv6_.get(), SIGNAL(newConnection()), this,
|
||||||
SLOT(AcceptConnection()));
|
SLOT(AcceptConnection()));
|
||||||
connect(web_channel_.get(), SIGNAL(Connected()), SLOT(AcceptWebConnection()));
|
connect(web_channel_.get(), SIGNAL(Connected()), SLOT(AcceptWebConnection()));
|
||||||
|
web_channel_->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkRemote::StartServer() {
|
void NetworkRemote::StartServer() {
|
||||||
|
@ -136,6 +137,7 @@ void NetworkRemote::AcceptConnection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkRemote::AcceptWebConnection() {
|
void NetworkRemote::AcceptWebConnection() {
|
||||||
|
qLog(Debug) << Q_FUNC_INFO;
|
||||||
ConnectSignals();
|
ConnectSignals();
|
||||||
|
|
||||||
WebRemoteClient* client = new WebRemoteClient(web_channel_.get(), app_, this);
|
WebRemoteClient* client = new WebRemoteClient(web_channel_.get(), app_, this);
|
||||||
|
|
|
@ -22,7 +22,7 @@ class RemoteClient : public QObject {
|
||||||
bool downloader() const { return downloader_; }
|
bool downloader() const { return downloader_; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ParseMessage(const QByteArray& data);
|
void Parse(const pb::remote::Message& msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application* app_;
|
Application* app_;
|
||||||
|
|
|
@ -25,9 +25,6 @@ class TcpRemoteClient : public RemoteClient {
|
||||||
private slots:
|
private slots:
|
||||||
void IncomingData();
|
void IncomingData();
|
||||||
|
|
||||||
signals:
|
|
||||||
void Parse(const pb::remote::Message& msg);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseMessage(const QByteArray& data);
|
void ParseMessage(const QByteArray& data);
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
#include "core/closure.h"
|
#include "core/closure.h"
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
#include "core/network.h"
|
#include "core/network.h"
|
||||||
|
#include "networkremote/clementinewebpage.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const char* kEndpoint = "http://localhost:8080/channel/push";
|
const char* kEndpoint = "http://localhost:8080/channel/clementine/push/%1";
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -17,6 +18,8 @@ WebRemoteClient::WebRemoteClient(
|
||||||
: RemoteClient(app, parent),
|
: RemoteClient(app, parent),
|
||||||
web_channel_(web_channel),
|
web_channel_(web_channel),
|
||||||
network_(new NetworkAccessManager) {
|
network_(new NetworkAccessManager) {
|
||||||
|
connect(web_channel, SIGNAL(MessageReceived(const pb::remote::Message&)),
|
||||||
|
SIGNAL(Parse(const pb::remote::Message&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRemoteClient::~WebRemoteClient() {}
|
WebRemoteClient::~WebRemoteClient() {}
|
||||||
|
@ -25,14 +28,18 @@ void WebRemoteClient::SendData(pb::remote::Message* msg) {
|
||||||
qLog(Debug) << "Sending:" << msg->DebugString().c_str();
|
qLog(Debug) << "Sending:" << msg->DebugString().c_str();
|
||||||
std::string data = msg->SerializeAsString();
|
std::string data = msg->SerializeAsString();
|
||||||
QByteArray base64 = QByteArray(data.data(), data.size()).toBase64();
|
QByteArray base64 = QByteArray(data.data(), data.size()).toBase64();
|
||||||
QNetworkRequest request = QNetworkRequest(QUrl(kEndpoint));
|
QNetworkRequest request = QNetworkRequest(
|
||||||
|
QUrl(QString(kEndpoint).arg(web_channel_->id())));
|
||||||
QNetworkReply* reply = network_->post(request, base64);
|
QNetworkReply* reply = network_->post(request, base64);
|
||||||
NewClosure(reply, SIGNAL(finished()), [&]() {
|
NewClosure(reply, SIGNAL(finished()),
|
||||||
|
this, SLOT(SendDataFinished(QNetworkReply*)), reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRemoteClient::SendDataFinished(QNetworkReply* reply) {
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
qLog(Debug) << reply->error()
|
qLog(Debug) << reply->error()
|
||||||
<< reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)
|
<< reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)
|
||||||
<< reply->readAll();
|
<< reply->readAll();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebRemoteClient::DisconnectClient(pb::remote::ReasonDisconnect reason) {
|
void WebRemoteClient::DisconnectClient(pb::remote::ReasonDisconnect reason) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
class ClementineWebPage;
|
class ClementineWebPage;
|
||||||
class NetworkAccessManager;
|
class NetworkAccessManager;
|
||||||
|
class QNetworkReply;
|
||||||
|
|
||||||
class WebRemoteClient : public RemoteClient {
|
class WebRemoteClient : public RemoteClient {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -20,6 +21,9 @@ class WebRemoteClient : public RemoteClient {
|
||||||
void DisconnectClient(pb::remote::ReasonDisconnect reason);
|
void DisconnectClient(pb::remote::ReasonDisconnect reason);
|
||||||
QAbstractSocket::SocketState state();
|
QAbstractSocket::SocketState state();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SendDataFinished(QNetworkReply*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClementineWebPage* web_channel_;
|
ClementineWebPage* web_channel_;
|
||||||
std::unique_ptr<NetworkAccessManager> network_;
|
std::unique_ptr<NetworkAccessManager> network_;
|
||||||
|
|
Loading…
Reference in New Issue