Advertisement
Guest User

TCPServerController.cpp

a guest
Jul 24th, 2021
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.25 KB | None | 0 0
  1. #include "tcp/tcpservercontroller.h"
  2. #include <QTcpServer>
  3.  
  4. /**
  5.  * Constructor generated by default.
  6.  */
  7. TCPServerController::TCPServerController()
  8. {
  9.     server = new QTcpServer(this);
  10.  
  11.     if (server->listen(QHostAddress::Any, 27556))
  12.     {
  13.         qDebug() << "[RPC SERVER]: listening on the port 27556...";
  14.         connect(server, &QTcpServer::newConnection, this, &TCPServerController::connected);
  15.     }
  16. }
  17.  
  18.  
  19. /**
  20.  * Procedure called on new connection.
  21.  */
  22. void TCPServerController::connected()
  23. {
  24.     qDebug() << "[RPC SERVER]: A client is connected.";
  25.  
  26.     QTcpSocket *newClientId = server->nextPendingConnection(); /** Generate a new pointer to represent the client. */
  27.  
  28.     connect(newClientId, &QTcpSocket::readyRead, this, &TCPServerController::receiveMessage); /** Listen if he sends a message. */
  29.     connect(newClientId, &QTcpSocket::disconnected, this, &TCPServerController::disconnected); /** Detect if the client disconnects. */
  30. }
  31.  
  32. /**
  33.  * Procedure called on new message.
  34.  */
  35. void TCPServerController::receiveMessage()
  36. {
  37.     QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
  38.     if (socket == 0)
  39.         return;
  40.  
  41.     QDataStream in(socket);
  42.  
  43.     if (heightPacket == 0)
  44.     {
  45.         if (socket->bytesAvailable() < (int)sizeof(quint16))
  46.             return;
  47.  
  48.         in >> heightPacket;
  49.     }
  50.  
  51.     if (socket->bytesAvailable() < heightPacket)
  52.         return;
  53.  
  54.     heightPacket = 0;
  55.  
  56.     QString message;
  57.     in >> message;
  58.  
  59.     qDebug() << "-->" << message;
  60.  
  61.     parse(message, socket);
  62. }
  63.  
  64. /**
  65.  * Procedure called to parse the JSON RPC request.
  66.  * @param message a constant QString argument.
  67.  * @param socket a pointer QTcpSocket argument.
  68.  */
  69. void TCPServerController::parse(QString const message, QTcpSocket *socket)
  70. {
  71.     QJsonDocument response { QJsonDocument::fromJson(message.toUtf8()) };
  72.  
  73.     QJsonObject payload, data { response.object() };
  74.  
  75.     QString method { data["method"].toString() };
  76.  
  77.     QJsonValue params { data["params"] };
  78.  
  79.     int cmdIndex { m_rpcManager.getCmdIndex(method.toStdString()) };
  80.  
  81.     /** JSON RPC verification */
  82.     if(cmdIndex == -1)
  83.     {
  84.         payload["code"] = -32601;
  85.         payload["message"] = "Method not found";
  86.  
  87.         sendMessage(socket, payload, false, true);
  88.  
  89.         return;
  90.     }
  91.  
  92.     if(m_rpcCmdAllowed[cmdIndex].nArgs != params.toObject().size())
  93.     {
  94.         payload["code"] = -32602;
  95.         payload["message"] = "Invalid params";
  96.  
  97.         sendMessage(socket, payload, false, true);
  98.  
  99.         return;
  100.     }
  101.  
  102.     if(data["id"].isNull())
  103.         return;
  104.  
  105.     /** Call the function */
  106.     std::function<QJsonObject(QJsonObject)> cmd { m_rpcCmdAllowed[cmdIndex].actor };
  107.     QJsonObject rpcResponse { cmd(params.toObject()) };
  108.  
  109.     /** JSON RPC on true connection */
  110.     if(method == "subscribe")
  111.         peerConnection(socket, params.toObject()); /** Register the peer's offer. */
  112.  
  113.     /** Send the response */
  114.     sendMessage(socket, rpcResponse);
  115. }
  116.  
  117. /**
  118.  * Procedure called to send a response following a protocol.
  119.  * @param socket a pointer QTcpSocket argument.
  120.  * @param paquet a QByteArray argument.
  121.  */
  122. void TCPServerController::protocolSend(QTcpSocket *socket, QByteArray paquet) {
  123.     socket->write(paquet);
  124.     socket->flush();
  125. }
  126.  
  127. /**
  128.  * Procedure called to send a response.
  129.  * @param socket a pointer QTcpSocket argument.
  130.  * @param params a constant QJsonObject argument.
  131.  * @param isBroadcast a constant boolean argument.
  132.  * @param error a constant boolean argument.
  133.  */
  134. void TCPServerController::sendMessage(QTcpSocket *socket, QJsonObject const params, bool const isBroadcast, bool const error)
  135. {
  136.     QJsonDocument rpcParams(params);
  137.  
  138.     QString keyName { error ? "error" : "result" }, rpcNotification { isBroadcast ? "" : ",\"id\":1" };
  139.  
  140.     QString rpcRequest { "{\"jsonrpc\":\"2.0\",\"" + keyName + "\":" + rpcParams.toJson(QJsonDocument::Compact) + rpcNotification + "}" };
  141.  
  142.     QByteArray paquet;
  143.     QDataStream out(&paquet, QIODevice::WriteOnly);
  144.  
  145.     out << (quint16) 0;
  146.     out << rpcRequest;
  147.     out.device()->seek(0);
  148.     out << (quint16) (paquet.size() - sizeof(quint16));
  149.  
  150.     if(isBroadcast)
  151.         foreach(peerInfo const client, peers)
  152.             protocolSend(client.serializationVersion, paquet);
  153.     else
  154.         protocolSend(socket, paquet);
  155. }
  156.  
  157. /**
  158.  * Procedure called to register the new pending connection.
  159.  * @param socket a pointer QTcpSocket argument.
  160.  * @param params a constant QJsonObject argument.
  161.  */
  162. void TCPServerController::peerConnection(QTcpSocket *socket, QJsonObject const params)
  163. {
  164.     peerInfo peer;
  165.  
  166.     peer.serializationVersion = socket;
  167.     peer.addr = QHostAddress(params["addr"].toString());
  168.     peer.addrlocal = QHostAddress(params["addrlocal"].toString());
  169.     peer.peer = params["peer"].toString();
  170.  
  171.     peers.push_back(peer);
  172. }
  173.  
  174. /**
  175.  * Procedure called on new disconnection.
  176.  */
  177. void TCPServerController::disconnected()
  178. {
  179.     qDebug() << "[RPC SERVER]: A client disconnected.";
  180.  
  181.     QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
  182.  
  183.     if (socket == 0)
  184.         return;
  185.  
  186.     if(findIndex(socket) != -1) {
  187.         qDebug() << "remove client";
  188.         peers.erase(peers.begin() + findIndex(socket));
  189.     }
  190.  
  191.     socket->deleteLater();
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement