fix: the deadlock issue with actively disconnected clients.

This commit is contained in:
2025-06-28 09:00:38 +08:00
parent b234ec8079
commit 3216356d66
2 changed files with 34 additions and 32 deletions

View File

@@ -11,8 +11,8 @@
| 序号 | 类型 | 内容 | 说明 | 基于版本 | 完成版本 | | 序号 | 类型 | 内容 | 说明 | 基于版本 | 完成版本 |
| :--: | :--: | ------------------------------------------------------------ | :--: | :------: | :------: | | :--: | :--: | ------------------------------------------------------------ | :--: | :------: | :------: |
| 18 | 问题 | 断开后重连貌似没有发送心跳包。 | | 0.1 | | | 18 | 问题 | 断开后重连貌似没有发送心跳包。 | | 0.1 | 0.2 |
| 17 | 问题 | 服务端主动踢出的客户端,主动重连假链接,不可用无反应。 | | 0.1 | | | 17 | 问题 | 服务端主动踢出的客户端,主动重连假链接,不可用无反应。 | | 0.1 | 0.2 |
| 16 | 优化 | 传输完成后接收端要刷新一次。 | | 0.1 | | | 16 | 优化 | 传输完成后接收端要刷新一次。 | | 0.1 | |
| 15 | 问题 | 拖动文件夹到对方,应当不处理,并日志提示。 | | 0.1 | | | 15 | 问题 | 拖动文件夹到对方,应当不处理,并日志提示。 | | 0.1 | |
| 14 | 功能 | 文件浏览部分添加右键复制全路径功能。 | | 0.1 | | | 14 | 功能 | 文件浏览部分添加右键复制全路径功能。 | | 0.1 | |

View File

@@ -87,27 +87,6 @@ void Server::onNewConnection()
sendData(clientSocket, frame); sendData(clientSocket, frame);
} }
void Server::onClientDisconnected()
{
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
}
QHostAddress peerAddress = socket->peerAddress();
quint32 ipv4 = peerAddress.toIPv4Address();
QString ipStr = QHostAddress(ipv4).toString();
QString clientId = QString("%1:%2").arg(ipStr).arg(socket->peerPort());
{
QWriteLocker locker(&rwLock_);
clients_.remove(clientId);
}
qDebug() << "Client disconnected:" << __LINE__ << clientId;
socket->deleteLater();
}
void Server::onReadyRead() void Server::onReadyRead()
{ {
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender()); QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
@@ -116,6 +95,7 @@ void Server::onReadyRead()
} }
QSharedPointer<ClientInfo> client; QSharedPointer<ClientInfo> client;
{ {
QReadLocker locker(&rwLock_); QReadLocker locker(&rwLock_);
client = clients_.value(socket->property("clientId").toString()); client = clients_.value(socket->property("clientId").toString());
@@ -230,21 +210,43 @@ bool Server::sendData(QTcpSocket* socket, QSharedPointer<FrameBuffer> frame)
return socket->write(data) == data.size(); return socket->write(data) == data.size();
} }
void Server::onClientDisconnected()
{
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
}
QString clientId = socket->property("clientId").toString();
{
QWriteLocker locker(&rwLock_);
if (clients_.count(clientId)) {
clients_.remove(clientId);
}
}
qDebug() << "Client disconnected:" << __LINE__ << clientId;
socket->deleteLater();
}
void Server::monitorClients() void Server::monitorClients()
{ {
qint64 now = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000; qint64 now = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000;
QWriteLocker locker(&rwLock_); std::vector<QTcpSocket*> prepareRemove;
for (auto it = clients_.begin(); it != clients_.end();) { {
auto t = now - it.value()->connectTime; QReadLocker locker(&rwLock_);
if (t > NO_HEATBEAT_TIMEOUT) { for (auto& c : clients_) {
qDebug() << "Disconnecting inactive client:" << it.value()->id; if (now - c->connectTime > NO_HEATBEAT_TIMEOUT) {
it.value()->socket->disconnectFromHost(); prepareRemove.push_back(c->socket);
it = clients_.erase(it); }
} else {
++it;
} }
} }
for (const auto& s : prepareRemove) {
qDebug() << "Removing inactive client:" << s->property("clientId").toString();
s->disconnectFromHost();
}
} }
QByteArray Server::getClients() QByteArray Server::getClients()