ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
jsonrpcserver.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "jsonrpcserver.h"
9 
10 #include <QJsonDocument>
11 #include <QJsonObject>
12 
14  : QObject(parent),
15  ws_server(new QWebSocketServer(QStringLiteral("CloudViewer"),
16  QWebSocketServer::NonSecureMode)) {
17  if (ws_server) {
18  connect(ws_server, &QWebSocketServer::newConnection, this,
19  &JsonRPCServer::onNewConnection);
20  connect(ws_server, &QWebSocketServer::closed, this,
21  &JsonRPCServer::onClosed);
22  }
23 }
24 
26  for (QWebSocket *conn : connections) {
27  conn->close();
28  delete conn;
29  }
30 }
31 
32 void JsonRPCServer::listen(unsigned int port) {
33  qDebug() << "JsonRPCServer::listen";
34  if (ws_server == nullptr) {
35  return;
36  }
37  if (ws_server->isListening()) {
38  ws_server->close();
39  }
40  ws_server->listen(QHostAddress::Any, port);
41 }
42 
44  qDebug() << "JsonRPCServer::close";
45  if (ws_server == nullptr) {
46  return;
47  }
48  ws_server->close();
49 
50  for (QWebSocket *conn : connections) {
51  conn->close();
52  conn->deleteLater();
53  }
54  connections.clear();
55 }
56 
57 void JsonRPCServer::onNewConnection() {
58  qDebug() << "JsonRPCServer::onNewConnection";
59  QWebSocket *pSocket = ws_server->nextPendingConnection();
60  if (pSocket == nullptr) {
61  return;
62  }
63  connect(pSocket, &QWebSocket::textMessageReceived, this,
64  &JsonRPCServer::processTextMessage);
65  connect(pSocket, &QWebSocket::binaryMessageReceived, this,
66  &JsonRPCServer::processBinaryMessage);
67  connect(pSocket, &QWebSocket::disconnected, this,
68  &JsonRPCServer::socketDisconnected);
69 
70  connections.append(pSocket);
71 }
72 
73 void JsonRPCServer::onClosed() { qDebug() << "JsonRPCServer::onClosed"; }
74 
75 void JsonRPCServer::processTextMessage(QString message) {
76  QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
77  qDebug() << "Message received:" << message;
78  if (pClient == nullptr) {
79  return;
80  }
81  QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
82  QJsonObject obj = doc.object();
83  auto method = obj.value("method").toString();
84  auto params = obj.value("params").toVariant().toMap();
85 
86  qDebug() << "method: " << method << ", params: " << params;
87  // check invalid JSON RPC
89  if (!method.isEmpty() && !obj.value("jsonrpc").toString().isEmpty()) {
90  // perform the RPC
91  result = emit execute(method, params);
92  } else {
93  result = JsonRPCResult::error(-32600, "Invalid Request");
94  }
95  // now build JSON response
96  if (!doc.object().contains("id")) {
97  // abort here, on notification there is NO RESPONSE
98  return;
99  }
100  QJsonObject response;
101  response["jsonrpc"] = "2.0";
102  response["id"] = obj.value("id");
103  if (result.isError) {
104  QJsonObject error;
105  error["code"] = result.error_code;
106  if (!result.error_message.isEmpty()) {
107  error["message"] = result.error_message;
108  }
109  response["error"] = error;
110  } else {
111  response["result"] = QJsonValue::fromVariant(result.result);
112  }
113 
114  pClient->sendTextMessage(QJsonDocument(response).toJson());
115 }
116 
117 void JsonRPCServer::processBinaryMessage(QByteArray message) {
118  QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
119  qDebug() << "Binary Message received:" << message;
120  if (pClient) {
121  pClient->sendBinaryMessage(message);
122  }
123 }
124 
125 void JsonRPCServer::socketDisconnected() {
126  QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
127  qDebug() << "socketDisconnected:" << pClient;
128  if (pClient) {
129  connections.removeAll(pClient);
130  pClient->deleteLater();
131  }
132 }
cmdLineReadable * params[]
core::Tensor result
Definition: VtkUtils.cpp:76
JsonRPCServer(QObject *parent=nullptr)
JsonRPCResult execute(QString method, QMap< QString, QVariant > params)
void listen(unsigned int port)
static void error(char *msg)
Definition: lsd.c:159
static JsonRPCResult error(int code, QString message)
Definition: jsonrpcserver.h:19