1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
#include <BALL/PYTHON/pyServer.h>
#include <BALL/COMMON/logStream.h>
#include <BALL/PYTHON/pyInterpreter.h>
#include <QtCore/QDataStream>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtNetwork/QTcpSocket>
using std::string;
using std::tie;
namespace BALL {
PyServer::PyServer()
{
if (!PyInterpreter::isInitialized())
{
Log.error() << "[PyServer] Server cannot be started as the Python interpreter is unavailable!" << std::endl;
return;
}
server_.reset(new QTcpServer());
server_->listen(QHostAddress::LocalHost, 8897u);
server_->connect(server_.get(), &QTcpServer::newConnection, [this]{ this->processRequest(); });
}
void PyServer::processRequest()
{
auto client = server_->nextPendingConnection();
if (!client) return;
client->waitForReadyRead(10000);
auto json = QJsonDocument::fromJson(client->readAll());
if (json.isNull() || !json.isObject())
{
client->write(createMessage("error", "[PyServer] ERROR: Invalid request"));
disconnectClient(client);
return;
}
auto request = json.object();
auto msg_type = request.take("msg_type");
auto content = request.take("content");
if ( msg_type == QJsonValue::Undefined || !msg_type.isString()
|| content == QJsonValue::Undefined || !content.isString())
{
client->write(createMessage("error", "[PyServer] ERROR: Invalid request"));
disconnectClient(client);
return;
}
// delegate request
if (msg_type.toString() == "execute_request")
{
processExecuteRequest(client, content.toString());
}
else
{
client->write(createMessage("error", "[PyServer] ERROR: Invalid request type"));
}
disconnectClient(client);
}
void PyServer::processExecuteRequest(QTcpSocket* client, const QString& content)
{
bool ok;
string res;
tie(ok, res) = PyInterpreter::run(content.toStdString());
if (!ok)
{
client->write(createMessage("error", PyInterpreter::getErrorMessage().c_str()));
return;
}
client->write(createMessage("execute_result", res.c_str()));
}
QByteArray PyServer::createMessage(QString msg_type, QString content)
{
QJsonObject msg;
msg["msg_type"] = msg_type;
msg["content"] = content;
if (msg["content"] == QJsonValue::Null)
{
msg["msg_type"] = "error";
msg["content"] = "[PyServer] ERROR: Output could not be generated; It was probably too large.";
}
return QJsonDocument(msg).toJson(QJsonDocument::Compact);
}
void PyServer::disconnectClient(QTcpSocket* client)
{
client->waitForBytesWritten(10000);
client->disconnectFromHost();
client->deleteLater();
}
}
|