#include "rpc_finsTcp.h" #include "qprocess.h" #include #include #include #include #include #include #include static QProcess* process = nullptr; static HANDLE jobHandle = nullptr; rpc_finsTcp* create() { qDebug() << "rpc_finsTcp create success!"; return new rpc_finsTcp; } void destory(rpc_finsTcp* ptr) { if (ptr) { delete ptr; ptr = nullptr; } qDebug() << " rpc_finsTcp destory success!"; } bool ifRun = true; rpc_finsTcp::rpc_finsTcp() { ifRun = true; } bool m_IsFinsTcp = false; rpc_finsTcp::~rpc_finsTcp() { qDebug() << " ~rpc_finsTcp success!"; } QQueue readDataQueue; // 从类中读数据到实例对象 QByteArray variantListToByteArray(const QVariant& var) { QByteArray byteArray; if (var.canConvert()) { QVariantList list = var.toList(); byteArray.reserve(list.size()); for (const QVariant& item : list) { // 每个元素转为 uchar 存入 QByteArray byteArray.append(static_cast(item.toInt())); } } return byteArray; } bool rpc_finsTcp::readData(std::vector& vec_mat, QByteArray& data) { JsonRpcClient* ptr = read_JsonRpcClient[data]; if(ptr == nullptr) { ptr = new JsonRpcClient("127.0.0.1", 9000); read_JsonRpcClient[data] = ptr; } //auto result = read_JsonRpcClient[data]->call("excuteCli", QJsonArray{ QString(data) }, "finstcp"); //data = variantListToByteArray(result); data = ptr->finsReadCall("excuteCli", QString(data), "finstcp"); return true; } bool ifRetryCMD = false; // 实例对象把数据写入到类 void startProcess(const QString& exePath) { if (process) return; // 避免重复启动 process = new QProcess(); process->setProgram(exePath); process->start(); if (!process->waitForStarted(1000)) { qDebug() << "Process failed to start."; delete process; process = nullptr; return; } DWORD pid = process->processId(); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); jobHandle = CreateJobObject(nullptr, nullptr); if (jobHandle == nullptr) { qDebug() << "Failed to create job object"; return; } JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {}; jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; SetInformationJobObject(jobHandle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)); if (!AssignProcessToJobObject(jobHandle, hProcess)) { qDebug() << "Failed to assign process to job object"; } CloseHandle(hProcess); } void stopProcess() { if (process) { if (process->state() == QProcess::Running) { process->kill(); process->waitForFinished(500); } delete process; process = nullptr; } if (jobHandle) { CloseHandle(jobHandle); jobHandle = nullptr; } } bool rpc_finsTcp::writeData(std::vector& vec_mat, QByteArray& data){ QList m_list = data.split('_'); if (m_list.size() < 4) { qCritical() << data + " m_list.size() != 4;command err"; return false; } QString m_value = m_list.at(3); QString commond = m_list.at(0); if (commond == "init") { m_IP = m_list.at(1); m_port = m_list.at(2).toInt(); } else if(data.contains("read")) { readDataQueue.append(data); } else { if(data.contains("Heart") == false) qDebug() << data; emit writeCallSignal("excuteCli", QJsonArray{ QString(data) }, "finstcp"); // } return true; } bool rpc_finsTcp::initParas(QByteArray& data){ startProcess("./json_rpc_server.exe"); subThread = new QThread(this); write_JsonRpcClient = new JsonRpcClientWorker(); write_JsonRpcClient->moveToThread(subThread); QObject::connect(this, &rpc_finsTcp::initRpcClient, write_JsonRpcClient, &JsonRpcClientWorker::initClient, Qt::QueuedConnection); emit initRpcClient(); QObject::connect(this, &rpc_finsTcp::writeCallSignal, write_JsonRpcClient, &JsonRpcClientWorker::writeCallSlot,Qt::QueuedConnection); subThread->start(); emit writeCallSignal("init", QJsonArray{ m_IP,m_port }, "finstcp"); while (write_JsonRpcClient->connection == None) QThread::msleep(1); if (write_JsonRpcClient->connection == Disconnected) { qDebug() << "JsonRpcClientSubThread connection failed!"; return false; } else if (write_JsonRpcClient->connection == Connected) { qDebug() << "JsonRpcClientSubThread connected successfully!"; } //qDebug() << "返回结果:" << result; //QList> batchList; //batchList << qMakePair(QString("read_short"), params) // << qMakePair(QString("read_bit"), QJsonObject{ {"bit", "M0"} }); //QJsonArray resultArray = _JsonRpcClient->batchCall(batchList); //qDebug() << "批量结果:" << resultArray; return true; } bool rpc_finsTcp::run() { // 没有用到 //qDebug() << "[info] " << __FUNCTION__ << " line:" << __LINE__ << " success!"; return true; } JsonRpcClient::JsonRpcClient(const QString& host, quint16 port) :host_(host), port_(port), idCounter_(1) { socket_.connectToHost(host_, port_); if (!socket_.waitForConnected(3000)) { qWarning() << "[JsonRpcClient] Initial connection failed:" << socket_.errorString(); _connectionStatus = Disconnected; } else { qDebug() << "[JsonRpcClient] Connected to" << host_ << ":" << port_; _connectionStatus = Connected; } } bool JsonRpcClient::reconnect() { if (socket_.state() == QAbstractSocket::ConnectedState) { return true; } socket_.abort(); // 清理旧连接 socket_.connectToHost(host_, port_); if (socket_.waitForConnected(3000)) { qDebug() << "[JsonRpcClient] Reconnected successfully."; return true; } else { qWarning() << "[JsonRpcClient] Reconnection failed:" << socket_.errorString(); return false; } } QVariant jsonToVariant(const nlohmann::json& j) { if (j.is_null()) return QVariant(); if (j.is_boolean()) return j.get(); if (j.is_number_integer()) return j.get(); if (j.is_number_unsigned()) return static_cast(j.get()); if (j.is_number_float()) return j.get(); if (j.is_string()) return QString::fromStdString(j.get()); if (j.is_array()) { QVariantList list; for (const auto& el : j) list.append(jsonToVariant(el)); return list; } if (j.is_object()) { QVariantMap map; for (auto it = j.begin(); it != j.end(); ++it) map[QString::fromStdString(it.key())] = jsonToVariant(it.value()); return map; } return QVariant(); // fallback } QVariant JsonRpcClient::call(const QString& method, const QJsonArray& params, const QString& module) { QMutexLocker locker(&mutex_); if (socket_.state() != QAbstractSocket::ConnectedState) { qWarning() << "[JsonRpcClient] Socket not connected."; if (!reconnect()) return QVariant(); } QString reqStr = QString(R"({"jsonrpc":"2.0","method":"%1","params":%2,"id":%3)") .arg(method) .arg(QString::fromUtf8(QJsonDocument(params).toJson(QJsonDocument::Compact))) .arg(idCounter_++); if (!module.isEmpty()) { reqStr += QString(R"(,"module":"%1")").arg(module); } reqStr += "}"; if (socket_.write(reqStr.toUtf8()) == -1 || !socket_.waitForBytesWritten(1000)) { qWarning() << "[JsonRpcClient] Write failed."; return QVariant(); } if (!socket_.waitForReadyRead(10000)) { qWarning() << "[JsonRpcClient] Read timeout."; return QVariant(); } QByteArray responseData = socket_.readAll(); // 使用 nlohmann json 替代 Qt 解析 try { auto respJson = nlohmann::json::parse(responseData.constData(), responseData.constData() + responseData.size()); if (respJson.contains("error")) { qWarning() << "[JsonRpcClient] Error:" << QString::fromStdString(respJson["error"].dump()); return QVariant(); } return jsonToVariant(respJson["result"]); } catch (const nlohmann::json::parse_error& e) { qWarning() << "[JsonRpcClient] Parse error:" << e.what(); return QVariant(); } } QByteArray JsonRpcClient::finsReadCall(const QString& method, const QString& params, const QString& module) { QMutexLocker locker(&mutex_); if (socket_.state() != QAbstractSocket::ConnectedState) { qWarning() << "[JsonRpcClient] Socket not connected."; if (!reconnect()) return QByteArray(); } QString reqStr = QString(R"({"jsonrpc":"2.0","method":"%1","params":["%2"],"id":%3)") .arg(method) .arg(params) .arg(idCounter_++); if (!module.isEmpty()) { reqStr += QString(R"(,"module":"%1")").arg(module); } reqStr += "}"; if (socket_.write(reqStr.toUtf8()) == -1 || !socket_.waitForBytesWritten(1000)) { qWarning() << "[JsonRpcClient] Write failed."; return QByteArray(); } if (!socket_.waitForReadyRead(10000)) { qWarning() << "[JsonRpcClient] Read timeout."; return QByteArray(); } QByteArray responseData = socket_.readAll(); // 仅用QByteArray查找和分割功能解析result数组 if (responseData.contains("error")) { qWarning() << "[JsonRpcClient] Error in response:" << responseData; return QByteArray(); } // 查找 "result": [ 和对应的 ] int resultPos = responseData.indexOf("\"result\""); if (resultPos == -1) { qWarning() << "[JsonRpcClient] No result field in response:" << responseData; return QByteArray(); } int arrayStart = responseData.indexOf('[', resultPos); int arrayEnd = responseData.indexOf(']', arrayStart); if (arrayStart == -1 || arrayEnd == -1 || arrayEnd <= arrayStart) { qWarning() << "[JsonRpcClient] Result array not found or malformed:" << responseData; return QByteArray(); } QByteArray arrayContent = responseData.mid(arrayStart + 1, arrayEnd - arrayStart - 1); // 按逗号分割 QList items = arrayContent.split(','); QByteArray result; for (QByteArray item : items) { item = item.trimmed(); bool ok = false; int val = item.toInt(&ok); if (ok) { result.append(static_cast(val)); } else if (!item.isEmpty()) { qWarning() << "[JsonRpcClient] Non-integer value in result array:" << item; return QByteArray(); } } return result; } void JsonRpcClient::writeCall(const QString& method, const QJsonArray& params, const QString& module) { if (socket_.state() != QAbstractSocket::ConnectedState) { qWarning() << "[JsonRpcClient] Socket not connected, trying to reconnect..."; if (!reconnect()) return; } QJsonObject request{ {"jsonrpc", "2.0"}, {"method", method}, {"params", params}, {"id", idCounter_++} }; if (!module.isEmpty()) { request["module"] = module; } QJsonDocument doc(request); QByteArray data = doc.toJson(QJsonDocument::Compact); if (socket_.write(data) == -1 || !socket_.waitForBytesWritten(1000)) { qWarning() << "[JsonRpcClient] Write failed:" << socket_.errorString(); return; } }