Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "tcp/tcpservercontroller.h"
- #include <QTcpServer>
- /**
- * Constructor generated by default.
- */
- TCPServerController::TCPServerController()
- {
- server = new QTcpServer(this);
- if (server->listen(QHostAddress::Any, 27556))
- {
- qDebug() << "[RPC SERVER]: listening on the port 27556...";
- connect(server, &QTcpServer::newConnection, this, &TCPServerController::connected);
- }
- }
- /**
- * Procedure called on new connection.
- */
- void TCPServerController::connected()
- {
- qDebug() << "[RPC SERVER]: A client is connected.";
- QTcpSocket *newClientId = server->nextPendingConnection(); /** Generate a new pointer to represent the client. */
- connect(newClientId, &QTcpSocket::readyRead, this, &TCPServerController::receiveMessage); /** Listen if he sends a message. */
- connect(newClientId, &QTcpSocket::disconnected, this, &TCPServerController::disconnected); /** Detect if the client disconnects. */
- }
- /**
- * Procedure called on new message.
- */
- void TCPServerController::receiveMessage()
- {
- QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
- if (socket == 0)
- return;
- QDataStream in(socket);
- if (heightPacket == 0)
- {
- if (socket->bytesAvailable() < (int)sizeof(quint16))
- return;
- in >> heightPacket;
- }
- if (socket->bytesAvailable() < heightPacket)
- return;
- heightPacket = 0;
- QString message;
- in >> message;
- qDebug() << "-->" << message;
- parse(message, socket);
- }
- /**
- * Procedure called to parse the JSON RPC request.
- * @param message a constant QString argument.
- * @param socket a pointer QTcpSocket argument.
- */
- void TCPServerController::parse(QString const message, QTcpSocket *socket)
- {
- QJsonDocument response { QJsonDocument::fromJson(message.toUtf8()) };
- QJsonObject payload, data { response.object() };
- QString method { data["method"].toString() };
- QJsonValue params { data["params"] };
- int cmdIndex { m_rpcManager.getCmdIndex(method.toStdString()) };
- /** JSON RPC verification */
- if(cmdIndex == -1)
- {
- payload["code"] = -32601;
- payload["message"] = "Method not found";
- sendMessage(socket, payload, false, true);
- return;
- }
- if(m_rpcCmdAllowed[cmdIndex].nArgs != params.toObject().size())
- {
- payload["code"] = -32602;
- payload["message"] = "Invalid params";
- sendMessage(socket, payload, false, true);
- return;
- }
- if(data["id"].isNull())
- return;
- /** Call the function */
- std::function<QJsonObject(QJsonObject)> cmd { m_rpcCmdAllowed[cmdIndex].actor };
- QJsonObject rpcResponse { cmd(params.toObject()) };
- /** JSON RPC on true connection */
- if(method == "subscribe")
- peerConnection(socket, params.toObject()); /** Register the peer's offer. */
- /** Send the response */
- sendMessage(socket, rpcResponse);
- }
- /**
- * Procedure called to send a response following a protocol.
- * @param socket a pointer QTcpSocket argument.
- * @param paquet a QByteArray argument.
- */
- void TCPServerController::protocolSend(QTcpSocket *socket, QByteArray paquet) {
- socket->write(paquet);
- socket->flush();
- }
- /**
- * Procedure called to send a response.
- * @param socket a pointer QTcpSocket argument.
- * @param params a constant QJsonObject argument.
- * @param isBroadcast a constant boolean argument.
- * @param error a constant boolean argument.
- */
- void TCPServerController::sendMessage(QTcpSocket *socket, QJsonObject const params, bool const isBroadcast, bool const error)
- {
- QJsonDocument rpcParams(params);
- QString keyName { error ? "error" : "result" }, rpcNotification { isBroadcast ? "" : ",\"id\":1" };
- QString rpcRequest { "{\"jsonrpc\":\"2.0\",\"" + keyName + "\":" + rpcParams.toJson(QJsonDocument::Compact) + rpcNotification + "}" };
- QByteArray paquet;
- QDataStream out(&paquet, QIODevice::WriteOnly);
- out << (quint16) 0;
- out << rpcRequest;
- out.device()->seek(0);
- out << (quint16) (paquet.size() - sizeof(quint16));
- if(isBroadcast)
- foreach(peerInfo const client, peers)
- protocolSend(client.serializationVersion, paquet);
- else
- protocolSend(socket, paquet);
- }
- /**
- * Procedure called to register the new pending connection.
- * @param socket a pointer QTcpSocket argument.
- * @param params a constant QJsonObject argument.
- */
- void TCPServerController::peerConnection(QTcpSocket *socket, QJsonObject const params)
- {
- peerInfo peer;
- peer.serializationVersion = socket;
- peer.addr = QHostAddress(params["addr"].toString());
- peer.addrlocal = QHostAddress(params["addrlocal"].toString());
- peer.peer = params["peer"].toString();
- peers.push_back(peer);
- }
- /**
- * Procedure called on new disconnection.
- */
- void TCPServerController::disconnected()
- {
- qDebug() << "[RPC SERVER]: A client disconnected.";
- QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
- if (socket == 0)
- return;
- if(findIndex(socket) != -1) {
- qDebug() << "remove client";
- peers.erase(peers.begin() + findIndex(socket));
- }
- socket->deleteLater();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement