Messages work both ways for web remote.

This commit is contained in:
John Maguire 2014-05-08 17:06:31 +02:00
parent 583c8bf419
commit d2c50c5298
10 changed files with 67 additions and 18 deletions

View File

@ -114,7 +114,6 @@ Application::Application(QObject* parent)
// Network Remote
ClementineWebPage* web_channel = new ClementineWebPage(this);
web_channel->mainFrame()->load(QUrl("http://localhost:8080/channel"));
network_remote_ = new NetworkRemote(web_channel, this);
MoveToNewThread(network_remote_);

View File

@ -4,6 +4,7 @@
#include <QNetworkCookie>
#include "config.h"
#include "remotecontrolmessages.pb.h"
#include "covers/albumcoverfetcher.h"
#include "engines/enginebase.h"
#include "engines/gstengine.h"
@ -82,6 +83,8 @@ void RegisterMetaTypes() {
qRegisterMetaType<Subdirectory>("Subdirectory");
qRegisterMetaType<QList<QUrl> >("QList<QUrl>");
qRegisterMetaType<pb::remote::Message>("pb::remote::Message");
#ifdef HAVE_VK
qRegisterMetaType<MusicOwner>("MusicOwner");
qRegisterMetaTypeStreamOperators<MusicOwner>("MusicOwner");

View File

@ -1,12 +1,20 @@
#include "clementinewebpage.h"
#include <QByteArray>
#include <QMetaObject>
#include <QThread>
#include <QWebFrame>
#include "core/closure.h"
#include "core/logging.h"
#include "remotecontrolmessages.pb.h"
namespace {
const char* kRemoteEndpoint = "http://localhost:8080/channel/remote/%1";
} // namespace
ClementineWebPage::ClementineWebPage(QObject* parent)
: QWebPage(parent) {
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(
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;
QByteArray bytes = QByteArray::fromBase64(message.toAscii());
@ -34,11 +62,8 @@ void ClementineWebPage::javaScriptConsoleMessage(
emit MessageReceived(msg);
}
void ClementineWebPage::javaScriptAlert(QWebFrame*, const QString& message) {
qLog(Debug) << message;
}
bool ClementineWebPage::shouldInterruptJavaScript() {
qLog(Debug) << Q_FUNC_INFO;
// Make sure any long-running js does not get interrupted.
return false;
}

View File

@ -7,6 +7,8 @@ class ClementineWebPage : public QWebPage {
public:
explicit ClementineWebPage(QObject* parent = nullptr);
void Init();
const QString id() const { return id_; }
public slots:
bool shouldInterruptJavaScript();
@ -15,9 +17,18 @@ class ClementineWebPage : public QWebPage {
void Connected();
void MessageReceived(const pb::remote::Message& msg);
private slots:
void InitOnMainThread();
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(
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_;
};

View File

@ -79,6 +79,7 @@ IncomingDataParser::~IncomingDataParser() {}
bool IncomingDataParser::close_connection() { return close_connection_; }
void IncomingDataParser::Parse(const pb::remote::Message& msg) {
qLog(Debug) << msg.DebugString().c_str();
close_connection_ = false;
RemoteClient* client = qobject_cast<RemoteClient*>(sender());

View File

@ -75,6 +75,7 @@ void NetworkRemote::SetupServer() {
connect(server_ipv6_.get(), SIGNAL(newConnection()), this,
SLOT(AcceptConnection()));
connect(web_channel_.get(), SIGNAL(Connected()), SLOT(AcceptWebConnection()));
web_channel_->Init();
}
void NetworkRemote::StartServer() {
@ -136,6 +137,7 @@ void NetworkRemote::AcceptConnection() {
}
void NetworkRemote::AcceptWebConnection() {
qLog(Debug) << Q_FUNC_INFO;
ConnectSignals();
WebRemoteClient* client = new WebRemoteClient(web_channel_.get(), app_, this);

View File

@ -22,7 +22,7 @@ class RemoteClient : public QObject {
bool downloader() const { return downloader_; }
signals:
void ParseMessage(const QByteArray& data);
void Parse(const pb::remote::Message& msg);
private:
Application* app_;

View File

@ -25,9 +25,6 @@ class TcpRemoteClient : public RemoteClient {
private slots:
void IncomingData();
signals:
void Parse(const pb::remote::Message& msg);
private:
void ParseMessage(const QByteArray& data);

View File

@ -5,10 +5,11 @@
#include "core/closure.h"
#include "core/logging.h"
#include "core/network.h"
#include "networkremote/clementinewebpage.h"
namespace {
const char* kEndpoint = "http://localhost:8080/channel/push";
const char* kEndpoint = "http://localhost:8080/channel/clementine/push/%1";
} // namespace
@ -17,6 +18,8 @@ WebRemoteClient::WebRemoteClient(
: RemoteClient(app, parent),
web_channel_(web_channel),
network_(new NetworkAccessManager) {
connect(web_channel, SIGNAL(MessageReceived(const pb::remote::Message&)),
SIGNAL(Parse(const pb::remote::Message&)));
}
WebRemoteClient::~WebRemoteClient() {}
@ -25,14 +28,18 @@ void WebRemoteClient::SendData(pb::remote::Message* msg) {
qLog(Debug) << "Sending:" << msg->DebugString().c_str();
std::string data = msg->SerializeAsString();
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);
NewClosure(reply, SIGNAL(finished()), [&]() {
reply->deleteLater();
qLog(Debug) << reply->error()
<< reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)
<< reply->readAll();
});
NewClosure(reply, SIGNAL(finished()),
this, SLOT(SendDataFinished(QNetworkReply*)), reply);
}
void WebRemoteClient::SendDataFinished(QNetworkReply* reply) {
reply->deleteLater();
qLog(Debug) << reply->error()
<< reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)
<< reply->readAll();
}
void WebRemoteClient::DisconnectClient(pb::remote::ReasonDisconnect reason) {

View File

@ -7,6 +7,7 @@
class ClementineWebPage;
class NetworkAccessManager;
class QNetworkReply;
class WebRemoteClient : public RemoteClient {
Q_OBJECT
@ -20,6 +21,9 @@ class WebRemoteClient : public RemoteClient {
void DisconnectClient(pb::remote::ReasonDisconnect reason);
QAbstractSocket::SocketState state();
private slots:
void SendDataFinished(QNetworkReply*);
private:
ClementineWebPage* web_channel_;
std::unique_ptr<NetworkAccessManager> network_;