rpc正常使用版本备份

This commit is contained in:
2025-07-25 00:29:52 +08:00
parent c971fe971e
commit 3d17218dad
56 changed files with 2226 additions and 692 deletions
+12
View File
@@ -0,0 +1,12 @@
# CMakeList.txt: 遍历文件夹 添加子项目
set(OUR_LIBS "")
SUBDIRENAMES(OUR_LIBS ${CMAKE_CURRENT_SOURCE_DIR} "" OFF)
message("OUR_LIBS :" ${OUR_LIBS})
# 遍历子库
foreach(dll ${OUR_LIBS})
add_subdirectory(${dll})
endforeach(dll ${})
+71
View File
@@ -0,0 +1,71 @@
# 获取获取当前目录名
get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(TIMESTAMP RUN_TIME)
message( " model start : " ${CURRENT_FOLDER}:${RUN_TIME})
set(DLL_NAMES "basler" "opencv")
foreach(child ${DLL_NAMES})
LIST(APPEND ENV_INCLUDE ${${child}_include})
LIST(APPEND ENV_LIB ${${child}_lib})
LIST(APPEND ENV_TARGET ${${child}_target_link})
endforeach()
message(" ENV_INCLUDE : " ${ENV_INCLUDE} )
message(" ENV_LIB : " ${ENV_LIB} )
message(" ENV_TARGET : " ${ENV_TARGET} )
include_directories(
${ENV_INCLUDE}
)
link_directories (
${ENV_LIB}
)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
FILE(GLOB HEAD_FILES "./*.h" )
FILE(GLOB SRC_FILES "./*.cpp")
FILE(GLOB UI_FILES "./*.ui")
#find_package(Qt5 COMPONENTS Core REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Network REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network REQUIRED)
add_library(${CURRENT_FOLDER} SHARED
${HEAD_FILES}
${SRC_FILES}
${UI_FILES}
)
set_target_properties(${CURRENT_FOLDER} PROPERTIES LINKER_LANGUAGE C
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
)
target_link_libraries(${CURRENT_FOLDER} PRIVATE
${ENV_TARGET}
Qt${QT_VERSION_MAJOR}::Core
Qt5::Network
)
# target_compile_definitions(${CURRENT_FOLDER} PRIVATE HD_AIDEMO_MODULE_LIBRARY)
string(TIMESTAMP RUN_TIME)
message( " model end : " ${CURRENT_FOLDER}:${RUN_TIME})
+275
View File
@@ -0,0 +1,275 @@
#include "rpc_finsTcp.h"
#include "qprocess.h"
#include <QHostAddress>
#include <QVariant>
#include <QDebug>
#include <QTcpSocket>
#include <QJsonObject>
#include <QJsonDocument>
#include <windows.h>
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<QByteArray> readDataQueue;
// 从类中读数据到实例对象
QByteArray variantListToByteArray(const QVariant& var) {
QByteArray byteArray;
if (var.canConvert<QVariantList>()) {
QVariantList list = var.toList();
byteArray.reserve(list.size());
for (const QVariant& item : list) {
// 每个元素转为 uchar 存入 QByteArray
byteArray.append(static_cast<char>(item.toInt()));
}
}
return byteArray;
}
bool rpc_finsTcp::readData(std::vector<cv::Mat>& 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);
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<cv::Mat>& vec_mat, QByteArray& data){
QList<QByteArray> 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 {
emit writeCallSignal("excuteCli", QJsonArray{ QString(data) }, "finstcp");
//qDebug() << data;
}
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");
//qDebug() << "返回结果:" << result;
//QList<QPair<QString, QJsonObject>> 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();
}
else {
qDebug() << "[JsonRpcClient] Connected to" << host_ << ":" << port_;
}
}
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 JsonRpcClient::call(const QString& method, const QJsonArray& params, const QString& module) {
QMutexLocker locker(&mutex_); // 确保线程安全
if (socket_.state() != QAbstractSocket::ConnectedState) {
qWarning() << "[JsonRpcClient] Socket not connected, trying to reconnect...";
if (!reconnect()) return QVariant();
}
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 QVariant();
}
if (!socket_.waitForReadyRead(3000)) {
qWarning() << "[JsonRpcClient] No response received:" << socket_.errorString();
return QVariant();
}
QByteArray responseData = socket_.readAll();
QJsonParseError parseError;
QJsonDocument respDoc = QJsonDocument::fromJson(responseData, &parseError);
if (parseError.error != QJsonParseError::NoError) {
qWarning() << "[JsonRpcClient] JSON parse error:" << parseError.errorString();
return QVariant();
}
QJsonObject resp = respDoc.object();
if (resp.contains("error")) {
qWarning() << "[JsonRpcClient] JSON-RPC error:" << resp["error"];
return QVariant();
}
return resp["result"].toVariant();
}
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;
}
}
+91
View File
@@ -0,0 +1,91 @@
#ifndef rpc_finsTcp_H
#define rpc_finsTcp_H
#include <QtCore/qglobal.h>
#include <QByteArray>
#include <iostream>
#include <QQueue>
#include <QDebug>
#include <subModuleBase.h>
#include <QMutex>
#include <QObject>
#include <QTcpSocket>
#include <QTimer>
#include <unordered_map>
#include <qjsonarray.h>
#include <QJsonObject>
#include <QJsonDocument>
#include <QHostAddress>
#include <qmap.h>
#include <qthread.h>
class JsonRpcClient : public QObject {
Q_OBJECT
public:
JsonRpcClient(const QString& host = "127.0.0.1", quint16 port = 9000);
void writeCall(const QString& method, const QJsonArray& params = {}, const QString& module = QString());
QVariant call(const QString& method, const QJsonArray& params = {}, const QString& module = QString());
bool reconnect(); // 主动重连,或 call() 失败时调用
private:
QMutex mutex_; // 确保线程安全
QTcpSocket socket_;
QString host_;
quint16 port_;
int idCounter_;
};
class JsonRpcClientWorker : public QObject {
Q_OBJECT
public:
QQueue<QByteArray> readDataQueue;
JsonRpcClientWorker() {
}
public slots:
void initClient() {
_JsonRpcClient = new JsonRpcClient();
}
void writeCallSlot(const QString& method, const QJsonArray& params, const QString& module = QString()) {
if (_JsonRpcClient) {
qDebug() << params;
_JsonRpcClient->call(method, params, module);
}
}
private:
JsonRpcClient* _JsonRpcClient = nullptr;
};
class rpc_finsTcp :public rpcModuleBase
{
Q_OBJECT
public:
rpc_finsTcp();
virtual ~rpc_finsTcp();
//bool readData(std::vector<cv::Mat>& vec_mat, QByteArray& data, nlohmann::json&); // readData将PLC读取或者发送的返回值发回给主线程,通过全局变量的方式逐条发送
//bool writeData(std::vector<cv::Mat>& vec_mat, QByteArray& data, nlohmann::json&); // writeData调用PLC的收发,将需要的数据发给寄存器,返回OK/NG
bool readData(std::vector<cv::Mat>&, QByteArray&);
bool writeData(std::vector<cv::Mat>&, QByteArray&);
bool initParas(QByteArray&);
bool run();
signals:
void initRpcClient();
void writeCallSignal(const QString& method, const QJsonArray& params, const QString& module);
private:
QMutex mutex;
QMap<QString,JsonRpcClient*> read_JsonRpcClient; // 存储多个 JsonRpcClient 实例
QThread* subThread;
JsonRpcClientWorker* write_JsonRpcClient;
QString m_IP;
int m_port;
QQueue<QByteArray> readDataQueue;
};
#pragma once
extern "C"
{
Q_DECL_EXPORT rpc_finsTcp * create();
Q_DECL_EXPORT void destory(rpc_finsTcp * ptr);
}
#endif // rpc_finsTcp_H