fix: the deadlock issue with actively disconnected clients.
This commit is contained in:
@@ -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 | |
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user