2025-06-18 11:11:08 +08:00
|
|
|
#include "ConnectControl.h"
|
2025-06-15 14:31:54 +08:00
|
|
|
|
|
|
|
|
#include <InfoMsg.h>
|
|
|
|
|
#include <InfoPack.hpp>
|
2025-06-27 22:13:52 +08:00
|
|
|
#include <QRegularExpression>
|
2025-06-15 14:31:54 +08:00
|
|
|
#include <future>
|
|
|
|
|
|
|
|
|
|
#include "GuiUtil/Public.h"
|
|
|
|
|
#include "ui_ConnectControl.h"
|
|
|
|
|
|
2025-06-19 11:59:32 +08:00
|
|
|
Connecter::Connecter(QWidget* parent) : QWidget(parent), ui(new Ui::Connecter)
|
2025-06-15 14:31:54 +08:00
|
|
|
{
|
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
InitControl();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Connecter::~Connecter()
|
|
|
|
|
{
|
|
|
|
|
delete ui;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-20 14:33:51 +08:00
|
|
|
void Connecter::RunWorker(ClientCore* clientCore)
|
2025-06-15 14:31:54 +08:00
|
|
|
{
|
|
|
|
|
clientCore_ = clientCore;
|
2025-06-19 15:37:39 +08:00
|
|
|
connect(clientCore_, &ClientCore::sigClients, this, &Connecter::HandleClients);
|
2025-06-20 14:33:51 +08:00
|
|
|
|
|
|
|
|
sockWorker_ = new SocketWorker(clientCore_, nullptr);
|
2025-06-26 22:09:04 +08:00
|
|
|
heatBeat_ = new HeatBeat(clientCore_);
|
2025-06-20 14:33:51 +08:00
|
|
|
clientCore_->moveToThread(sockWorker_);
|
|
|
|
|
|
|
|
|
|
connect(clientCore_, &ClientCore::conSuccess, this, [this]() {
|
|
|
|
|
setState(ConnectState::CS_CONNECTED);
|
2025-11-04 15:18:28 +08:00
|
|
|
qInfo() << QString(tr("已连接。"));
|
2025-06-20 14:33:51 +08:00
|
|
|
});
|
|
|
|
|
|
2025-10-21 09:48:20 +08:00
|
|
|
connect(clientCore_, &ClientCore::sigYourId, this,
|
|
|
|
|
[this](QSharedPointer<FrameBuffer> frame) { ui->edOwnID->setText(frame->data); });
|
|
|
|
|
|
2025-06-20 14:33:51 +08:00
|
|
|
connect(clientCore_, &ClientCore::conFailed, this, [this]() {
|
|
|
|
|
setState(ConnectState::CS_DISCONNECT);
|
2025-11-04 15:18:28 +08:00
|
|
|
qInfo() << QString(tr("连接失败。"));
|
2025-06-20 14:33:51 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(clientCore_, &ClientCore::connecting, this, [this]() {
|
|
|
|
|
setState(ConnectState::CS_CONNECTING);
|
2025-11-04 15:18:28 +08:00
|
|
|
qInfo() << QString(tr("连接中......"));
|
2025-06-20 14:33:51 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(clientCore_, &ClientCore::sigDisconnect, this, [this]() {
|
|
|
|
|
setState(ConnectState::CS_DISCONNECT);
|
2025-06-26 23:09:48 +08:00
|
|
|
QStandardItemModel* model = qobject_cast<QStandardItemModel*>(ui->listView->model());
|
|
|
|
|
if (model) {
|
|
|
|
|
model->clear();
|
|
|
|
|
}
|
2025-06-27 22:18:41 +08:00
|
|
|
ui->elbClient->clear();
|
|
|
|
|
clientCore_->SetRemoteID("");
|
2025-10-20 17:12:39 +08:00
|
|
|
ui->edOwnID->setText("");
|
2025-11-04 15:18:28 +08:00
|
|
|
qInfo() << QString(tr("已断开。"));
|
2025-06-20 14:33:51 +08:00
|
|
|
});
|
2025-10-20 16:40:52 +08:00
|
|
|
connect(clientCore_, &ClientCore::sigOffline, this, [this]() {
|
|
|
|
|
ui->elbClient->clear();
|
|
|
|
|
clientCore_->SetRemoteID("");
|
|
|
|
|
RefreshClient();
|
|
|
|
|
});
|
2025-06-20 14:33:51 +08:00
|
|
|
|
|
|
|
|
connect(this, &Connecter::sigDoConnect, clientCore_, &ClientCore::DoConnect);
|
2025-06-26 22:59:58 +08:00
|
|
|
connect(this, &Connecter::sigDisConnect, this,
|
|
|
|
|
[this]() { QMetaObject::invokeMethod(clientCore_, "Disconnect", Qt::QueuedConnection); });
|
2025-06-20 14:33:51 +08:00
|
|
|
connect(sockWorker_, &QThread::finished, sockWorker_, &QObject::deleteLater);
|
|
|
|
|
|
2025-06-26 22:09:04 +08:00
|
|
|
heatBeat_->start();
|
2025-06-20 14:33:51 +08:00
|
|
|
sockWorker_->start();
|
2025-06-15 14:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Connecter::SetRemoteCall(const std::function<void(const QString& id)>& call)
|
|
|
|
|
{
|
|
|
|
|
remoteCall_ = call;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Connecter::HandleClients(const InfoClientVec& clients)
|
|
|
|
|
{
|
|
|
|
|
model_->removeRows(0, ui->listView->model()->rowCount());
|
|
|
|
|
for (const auto& client : clients.vec) {
|
2025-06-15 20:37:25 +08:00
|
|
|
auto* item = new QStandardItem(client.id);
|
2025-10-20 17:12:39 +08:00
|
|
|
if (client.id == GlobalData::Ins()->GetLocalID()) {
|
|
|
|
|
item->setForeground(QColor("red"));
|
|
|
|
|
}
|
2025-06-15 14:31:54 +08:00
|
|
|
model_->appendRow(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-27 22:13:52 +08:00
|
|
|
void Connecter::SetConfigPtr(std::shared_ptr<FrelayConfig> config)
|
|
|
|
|
{
|
|
|
|
|
config_ = config;
|
|
|
|
|
auto ipPorts = config_->GetIpPort();
|
|
|
|
|
for (const auto& ipPort : ipPorts) {
|
|
|
|
|
ui->comboBox->addItem(ipPort);
|
|
|
|
|
}
|
|
|
|
|
if (ui->comboBox->count() > 0) {
|
|
|
|
|
ui->comboBox->setCurrentIndex(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-15 14:31:54 +08:00
|
|
|
void Connecter::Connect()
|
|
|
|
|
{
|
2025-06-27 22:13:52 +08:00
|
|
|
QString ip;
|
|
|
|
|
QString port;
|
|
|
|
|
if (!parseIpPort(ui->comboBox->currentText(), ip, port)) {
|
2025-11-04 14:52:27 +08:00
|
|
|
FTCommon::msg(this, QString(tr("IP或者端口不合法。")));
|
2025-06-15 14:31:54 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2025-06-20 14:33:51 +08:00
|
|
|
emit sigDoConnect(ip, port.toInt());
|
2025-06-15 14:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Connecter::setState(ConnectState cs)
|
|
|
|
|
{
|
2025-06-27 22:13:52 +08:00
|
|
|
config_->SaveIpPort(ui->comboBox->currentText());
|
2025-06-15 14:31:54 +08:00
|
|
|
switch (cs) {
|
|
|
|
|
case CS_CONNECTING:
|
|
|
|
|
ui->btnConnect->setEnabled(false);
|
|
|
|
|
ui->btnDisconnect->setEnabled(false);
|
|
|
|
|
break;
|
|
|
|
|
case CS_CONNECTED:
|
|
|
|
|
ui->btnConnect->setEnabled(false);
|
|
|
|
|
ui->btnDisconnect->setEnabled(true);
|
2025-06-25 16:15:25 +08:00
|
|
|
RefreshClient();
|
2025-06-26 22:09:04 +08:00
|
|
|
connect(heatBeat_, &HeatBeat::finished, heatBeat_, &QObject::deleteLater);
|
2025-06-15 14:31:54 +08:00
|
|
|
break;
|
|
|
|
|
case CS_DISCONNECT:
|
|
|
|
|
ui->btnConnect->setEnabled(true);
|
|
|
|
|
ui->btnDisconnect->setEnabled(false);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-19 17:01:25 +08:00
|
|
|
void Connecter::Disconnect()
|
|
|
|
|
{
|
2025-11-04 14:52:27 +08:00
|
|
|
qWarning() << QString(tr("断开连接。"));
|
2025-06-20 14:39:03 +08:00
|
|
|
emit sigDisConnect();
|
2025-06-19 17:01:25 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-15 14:31:54 +08:00
|
|
|
void Connecter::RefreshClient()
|
|
|
|
|
{
|
|
|
|
|
InfoMsg info;
|
|
|
|
|
auto frame = QSharedPointer<FrameBuffer>::create();
|
|
|
|
|
frame->data = infoPack(info);
|
|
|
|
|
frame->type = FBT_SER_MSG_ASKCLIENTS;
|
2025-06-25 10:54:04 +08:00
|
|
|
auto sendRet = ClientCore::syncInvoke(clientCore_, frame);
|
2025-06-19 11:59:32 +08:00
|
|
|
if (!sendRet) {
|
2025-11-04 14:52:27 +08:00
|
|
|
qCritical() << QString(tr("请求查询客户端列表失败。"));
|
2025-06-15 14:31:54 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2025-11-04 15:18:28 +08:00
|
|
|
qInfo() << QString(tr("刷新在线客户端列表。"));
|
2025-06-15 14:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Connecter::ShowContextMenu(const QPoint& pos)
|
|
|
|
|
{
|
|
|
|
|
auto index = ui->listView->indexAt(pos);
|
|
|
|
|
|
|
|
|
|
if (!index.isValid()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
menu_->exec(QCursor::pos());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string Connecter::getCurClient()
|
|
|
|
|
{
|
|
|
|
|
return ui->elbClient->text().toStdString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Connecter::InitControl()
|
|
|
|
|
{
|
2025-10-20 17:12:39 +08:00
|
|
|
ui->edOwnID->setReadOnly(true);
|
|
|
|
|
ui->label->setStyleSheet("color: blue;");
|
|
|
|
|
ui->edOwnID->setStyleSheet("color: blue;");
|
|
|
|
|
|
2025-06-15 14:31:54 +08:00
|
|
|
ui->btnDisconnect->setEnabled(false);
|
2025-06-27 22:13:52 +08:00
|
|
|
ui->comboBox->setEditable(true);
|
2025-06-25 23:49:40 +08:00
|
|
|
|
2025-06-15 14:31:54 +08:00
|
|
|
connect(ui->btnConnect, &QPushButton::clicked, this, &Connecter::Connect);
|
|
|
|
|
connect(ui->btnRefresh, &QPushButton::clicked, this, &Connecter::RefreshClient);
|
|
|
|
|
connect(this, &Connecter::sendConnect, this, &Connecter::setState);
|
|
|
|
|
|
|
|
|
|
model_ = new QStandardItemModel(this);
|
|
|
|
|
ui->listView->setModel(model_);
|
|
|
|
|
ui->listView->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
|
|
|
|
|
|
connect(ui->listView, &QListView::customContextMenuRequested, this, &Connecter::ShowContextMenu);
|
2025-06-19 17:01:25 +08:00
|
|
|
connect(ui->btnDisconnect, &QPushButton::clicked, this, &Connecter::Disconnect);
|
2025-06-15 14:31:54 +08:00
|
|
|
|
|
|
|
|
menu_ = new QMenu(this);
|
|
|
|
|
QAction* acUseThis = menu_->addAction(tr("UseThis"));
|
|
|
|
|
connect(acUseThis, &QAction::triggered, this, [this]() {
|
|
|
|
|
auto index = ui->listView->currentIndex();
|
|
|
|
|
if (!index.isValid()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
auto* item = model_->itemFromIndex(index);
|
|
|
|
|
if (!item) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
auto name = item->text();
|
|
|
|
|
ui->elbClient->setText(name);
|
2025-06-21 02:50:05 +08:00
|
|
|
ui->elbClient->setStyleSheet("color: green;");
|
2025-06-15 14:31:54 +08:00
|
|
|
remoteCall_(name);
|
2025-06-26 00:19:45 +08:00
|
|
|
emit sigConfirmUse();
|
2025-06-15 14:31:54 +08:00
|
|
|
});
|
|
|
|
|
|
2025-06-20 14:58:47 +08:00
|
|
|
setMaximumWidth(300);
|
2025-06-15 14:31:54 +08:00
|
|
|
}
|
2025-06-27 22:13:52 +08:00
|
|
|
|
|
|
|
|
bool Connecter::parseIpPort(const QString& ipPort, QString& outIp, QString& outPort)
|
|
|
|
|
{
|
|
|
|
|
QRegularExpression regex("^\\s*"
|
|
|
|
|
"("
|
|
|
|
|
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
|
|
|
|
|
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
|
|
|
|
|
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
|
|
|
|
|
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
|
|
|
|
|
")"
|
|
|
|
|
"\\s*:\\s*"
|
|
|
|
|
"("
|
|
|
|
|
"\\d{1,5}"
|
|
|
|
|
")"
|
|
|
|
|
"\\s*$");
|
|
|
|
|
|
|
|
|
|
QRegularExpressionMatch match = regex.match(ipPort);
|
|
|
|
|
if (!match.hasMatch()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
outIp = match.captured(1);
|
|
|
|
|
outPort = match.captured(2);
|
|
|
|
|
|
|
|
|
|
bool portOk;
|
|
|
|
|
int portNum = outPort.toInt(&portOk);
|
|
|
|
|
return portOk && portNum > 0 && portNum <= 65535;
|
|
|
|
|
}
|