mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
added skeleton for the json connection server
This commit is contained in:
parent
2c97353a11
commit
16c260b3dc
36
include/jsonserver/JsonServer.h
Normal file
36
include/jsonserver/JsonServer.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
// system includes
|
||||
#include <cstdint>
|
||||
|
||||
// Qt includes
|
||||
#include <QTcpServer>
|
||||
#include <QSet>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/Hyperion.h>
|
||||
|
||||
class JsonClientConnection;
|
||||
|
||||
class JsonServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
JsonServer(Hyperion * hyperion, uint16_t port = 19444);
|
||||
~JsonServer();
|
||||
|
||||
uint16_t getPort() const;
|
||||
|
||||
private slots:
|
||||
void newConnection();
|
||||
|
||||
void closedConnection(JsonClientConnection * connection);
|
||||
|
||||
private:
|
||||
Hyperion * _hyperion;
|
||||
|
||||
QTcpServer _server;
|
||||
|
||||
QSet<JsonClientConnection *> _openConnections;
|
||||
};
|
@ -4,4 +4,5 @@ SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include)
|
||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc)
|
||||
|
||||
add_subdirectory(hyperion)
|
||||
add_subdirectory(jsonserver)
|
||||
add_subdirectory(utils)
|
||||
|
36
libsrc/jsonserver/CMakeLists.txt
Normal file
36
libsrc/jsonserver/CMakeLists.txt
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
# Define the current source locations
|
||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/jsonserver)
|
||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/jsonserver)
|
||||
|
||||
# Group the headers that go through the MOC compiler
|
||||
SET(JsonServer_QT_HEADERS
|
||||
${CURRENT_HEADER_DIR}/JsonServer.h
|
||||
${CURRENT_SOURCE_DIR}/JsonClientConnection.h
|
||||
)
|
||||
|
||||
SET(JsonServer_HEADERS
|
||||
)
|
||||
|
||||
SET(JsonServer_SOURCES
|
||||
${CURRENT_SOURCE_DIR}/JsonServer.cpp
|
||||
${CURRENT_SOURCE_DIR}/JsonClientConnection.cpp
|
||||
)
|
||||
|
||||
qt4_wrap_cpp(JsonServer_HEADERS_MOC ${JsonServer_QT_HEADERS})
|
||||
|
||||
add_library(jsonserver
|
||||
${JsonServer_HEADERS}
|
||||
${JsonServer_QT_HEADERS}
|
||||
${JsonServer_HEADERS_MOC}
|
||||
${JsonServer_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(jsonserver
|
||||
hyperion
|
||||
jsoncpp)
|
||||
|
||||
qt4_use_modules(jsonserver
|
||||
Core
|
||||
Gui
|
||||
Network)
|
77
libsrc/jsonserver/JsonClientConnection.cpp
Normal file
77
libsrc/jsonserver/JsonClientConnection.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
// stl includes
|
||||
#include <iostream>
|
||||
|
||||
#include "JsonClientConnection.h"
|
||||
|
||||
JsonClientConnection::JsonClientConnection(QTcpSocket *socket) :
|
||||
QObject(),
|
||||
_socket(socket)
|
||||
{
|
||||
connect(_socket, SIGNAL(disconnected()), this, SLOT(socketClosed()));
|
||||
connect(_socket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
}
|
||||
|
||||
|
||||
JsonClientConnection::~JsonClientConnection()
|
||||
{
|
||||
delete _socket;
|
||||
}
|
||||
|
||||
void JsonClientConnection::readData()
|
||||
{
|
||||
_receiveBuffer += _socket->readAll();
|
||||
|
||||
int bytes = _receiveBuffer.indexOf('\n') + 1;
|
||||
if (bytes != 0)
|
||||
{
|
||||
// create message string
|
||||
std::string message(_receiveBuffer.data(), bytes);
|
||||
|
||||
// remove message data from buffer
|
||||
_receiveBuffer = _receiveBuffer.mid(bytes);
|
||||
|
||||
// handle message
|
||||
handleMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
void JsonClientConnection::socketClosed()
|
||||
{
|
||||
emit connectionClosed(this);
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleMessage(const std::string &message)
|
||||
{
|
||||
Json::Reader reader;
|
||||
Json::Value messageRoot;
|
||||
if (!reader.parse(message, messageRoot, false))
|
||||
{
|
||||
sendErrorReply("Error while parsing json: " + reader.getFormattedErrorMessages());
|
||||
return;
|
||||
}
|
||||
|
||||
handleNotImplemented(messageRoot);
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleNotImplemented(const Json::Value & message)
|
||||
{
|
||||
sendErrorReply("Command not implemented");
|
||||
}
|
||||
|
||||
void JsonClientConnection::sendMessage(const Json::Value &message)
|
||||
{
|
||||
Json::FastWriter writer;
|
||||
std::string serializedReply = writer.write(message);
|
||||
_socket->write(serializedReply.data(), serializedReply.length());
|
||||
}
|
||||
|
||||
void JsonClientConnection::sendErrorReply(const std::string &error)
|
||||
{
|
||||
// create reply
|
||||
Json::Value reply;
|
||||
reply["success"] = false;
|
||||
reply["error"] = error;
|
||||
|
||||
// send reply
|
||||
sendMessage(reply);
|
||||
}
|
39
libsrc/jsonserver/JsonClientConnection.h
Normal file
39
libsrc/jsonserver/JsonClientConnection.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
// stl includes
|
||||
#include <string>
|
||||
|
||||
// Qt includes
|
||||
#include <QByteArray>
|
||||
#include <QTcpSocket>
|
||||
|
||||
// jsoncpp includes
|
||||
#include <json/json.h>
|
||||
|
||||
class JsonClientConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
JsonClientConnection(QTcpSocket * socket);
|
||||
~JsonClientConnection();
|
||||
|
||||
signals:
|
||||
void connectionClosed(JsonClientConnection * connection);
|
||||
|
||||
private slots:
|
||||
void readData();
|
||||
void socketClosed();
|
||||
|
||||
private:
|
||||
void handleMessage(const std::string & message);
|
||||
void handleNotImplemented(const Json::Value & message);
|
||||
|
||||
void sendMessage(const Json::Value & message);
|
||||
void sendErrorReply(const std::string & error);
|
||||
|
||||
private:
|
||||
QTcpSocket * _socket;
|
||||
|
||||
QByteArray _receiveBuffer;
|
||||
};
|
57
libsrc/jsonserver/JsonServer.cpp
Normal file
57
libsrc/jsonserver/JsonServer.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
// system includes
|
||||
#include <stdexcept>
|
||||
|
||||
// project includes
|
||||
#include <jsonserver/JsonServer.h>
|
||||
#include "JsonClientConnection.h"
|
||||
|
||||
JsonServer::JsonServer(Hyperion *hyperion, uint16_t port) :
|
||||
QObject(),
|
||||
_hyperion(hyperion),
|
||||
_server(),
|
||||
_openConnections()
|
||||
{
|
||||
if (!_server.listen(QHostAddress::Any, port))
|
||||
{
|
||||
throw std::runtime_error("Json server could not bind to port");
|
||||
}
|
||||
|
||||
// Set trigger for incoming connections
|
||||
connect(&_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
|
||||
}
|
||||
|
||||
JsonServer::~JsonServer()
|
||||
{
|
||||
foreach (JsonClientConnection * connection, _openConnections) {
|
||||
delete connection;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t JsonServer::getPort() const
|
||||
{
|
||||
return _server.serverPort();
|
||||
}
|
||||
|
||||
void JsonServer::newConnection()
|
||||
{
|
||||
std::cout << "New incoming json connection" << std::endl;
|
||||
QTcpSocket * socket = _server.nextPendingConnection();
|
||||
|
||||
if (socket != nullptr)
|
||||
{
|
||||
JsonClientConnection * connection = new JsonClientConnection(socket);
|
||||
_openConnections.insert(connection);
|
||||
|
||||
// register slot for cleaning up after the connection closed
|
||||
connect(connection, SIGNAL(connectionClosed(JsonClientConnection*)), this, SLOT(closedConnection(JsonClientConnection*)));
|
||||
}
|
||||
}
|
||||
|
||||
void JsonServer::closedConnection(JsonClientConnection *connection)
|
||||
{
|
||||
std::cout << "Json connection closed" << std::endl;
|
||||
_openConnections.remove(connection);
|
||||
|
||||
// schedule to delete the connection object
|
||||
connection->deleteLater();
|
||||
}
|
@ -6,7 +6,8 @@ add_executable(hyperiond
|
||||
hyperion-d.cpp)
|
||||
|
||||
target_link_libraries(hyperiond
|
||||
hyperion)
|
||||
hyperion
|
||||
jsonserver)
|
||||
|
||||
# Find the libPNG
|
||||
find_package(PNG QUIET)
|
||||
|
@ -9,6 +9,9 @@
|
||||
#include <hyperion/DispmanxWrapper.h>
|
||||
#include <hyperion/Hyperion.h>
|
||||
|
||||
// JsonServer includes
|
||||
#include <jsonserver/JsonServer.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// Initialising QCoreApplication
|
||||
@ -16,9 +19,9 @@ int main(int argc, char** argv)
|
||||
std::cout << "QCoreApplication initialised" << std::endl;
|
||||
|
||||
// Select config and schema file
|
||||
const std::string homeDir = getenv("RASPILIGHT_HOME");
|
||||
const std::string schemaFile = homeDir + "/hyperion.schema.json";
|
||||
const std::string configFile = homeDir + "/hyperion.config.json";
|
||||
//const std::string homeDir = getenv("RASPILIGHT_HOME");
|
||||
const std::string schemaFile = "hyperion.schema.json";
|
||||
const std::string configFile = "hyperion.config.json";
|
||||
|
||||
// Load configuration and check against the schema at the same time
|
||||
Json::Value config;
|
||||
@ -36,6 +39,9 @@ int main(int argc, char** argv)
|
||||
dispmanx.start();
|
||||
std::cout << "Frame grabber created and started" << std::endl;
|
||||
|
||||
JsonServer jsonServer(&hyperion);
|
||||
std::cout << "Json server created and started on port " << jsonServer.getPort() << std::endl;
|
||||
|
||||
app.exec();
|
||||
std::cout << "Application closed" << std::endl;
|
||||
}
|
||||
|
@ -210,16 +210,15 @@ void JsonConnection::setTransform(ColorTransformValues *threshold, ColorTransfor
|
||||
|
||||
Json::Value JsonConnection::sendMessage(const Json::Value & message)
|
||||
{
|
||||
// serialize message (FastWriter already appends a newline)
|
||||
std::string serializedMessage = Json::FastWriter().write(message);
|
||||
|
||||
// print command if requested
|
||||
if (_printJson)
|
||||
{
|
||||
std::cout << "Command: " << message << std::endl;
|
||||
std::cout << "Command: " << serializedMessage;
|
||||
}
|
||||
|
||||
// serialize message (FastWriter already appends a newline
|
||||
Json::FastWriter jsonWriter;
|
||||
std::string serializedMessage = jsonWriter.write(message);
|
||||
|
||||
// write message
|
||||
_socket.write(serializedMessage.c_str());
|
||||
if (!_socket.waitForBytesWritten())
|
||||
@ -241,6 +240,12 @@ Json::Value JsonConnection::sendMessage(const Json::Value & message)
|
||||
}
|
||||
int bytes = serializedReply.indexOf('\n') + 1; // Find the end of message
|
||||
|
||||
// print reply if requested
|
||||
if (_printJson)
|
||||
{
|
||||
std::cout << "Reply: " << std::string(serializedReply.data(), bytes);
|
||||
}
|
||||
|
||||
// parse reply data
|
||||
Json::Reader jsonReader;
|
||||
Json::Value reply;
|
||||
@ -249,12 +254,6 @@ Json::Value JsonConnection::sendMessage(const Json::Value & message)
|
||||
throw std::runtime_error("Error while parsing reply: invalid json");
|
||||
}
|
||||
|
||||
// print reply if requested
|
||||
if (_printJson)
|
||||
{
|
||||
std::cout << "Reply:" << reply << std::endl;
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
@ -271,12 +270,12 @@ bool JsonConnection::parseReply(const Json::Value &reply)
|
||||
}
|
||||
catch (const std::runtime_error &)
|
||||
{
|
||||
// Some json paring error: ignore and set parsing error
|
||||
// Some json parsing error: ignore and set parsing error
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
throw std::runtime_error("Error while paring reply: " + reason);
|
||||
throw std::runtime_error("Error while executing command: " + reason);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
Loading…
Reference in New Issue
Block a user