mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-09 22:06:09 +08:00
refactor: improve resource cleanup logic on network battle exit
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "NetworkManager.h"
|
||||
|
||||
#include "utils/ConfigLoader.h"
|
||||
#include <iostream>
|
||||
NetworkManager::NetworkManager()
|
||||
@@ -9,10 +10,30 @@ NetworkManager::NetworkManager()
|
||||
}
|
||||
|
||||
NetworkManager::~NetworkManager() {
|
||||
std::cout << "NetworkManager destructor called\n";
|
||||
|
||||
// 1. 先取消所有异步操作
|
||||
if (m_gameServer) {
|
||||
m_gameServer->stop();
|
||||
}
|
||||
|
||||
if (m_client) {
|
||||
m_client->closeConnection();
|
||||
}
|
||||
|
||||
// 2. 等待一小段时间让异步操作处理完成
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
// 3. 停止 io_context
|
||||
m_ioContext.stop();
|
||||
|
||||
// 4. 等待线程结束
|
||||
if (m_ioThread.joinable()) {
|
||||
m_ioThread.join();
|
||||
std::cout << "Network thread joined\n";
|
||||
}
|
||||
|
||||
std::cout << "NetworkManager destroyed\n";
|
||||
}
|
||||
|
||||
void NetworkManager::init(NetType type) {
|
||||
@@ -101,9 +122,11 @@ void NetworkManager::startClient() {
|
||||
}
|
||||
std::cout << "start client success\n";
|
||||
startIOContextLoop();
|
||||
|
||||
}
|
||||
|
||||
void NetworkManager::startIOContextLoop() {
|
||||
|
||||
|
||||
m_ioThread = std::thread([this]() {
|
||||
try {
|
||||
@@ -136,4 +159,4 @@ void NetworkManager::setIsMyTurn(bool isMyTurn) {
|
||||
m_client->setShouldWait(!isMyTurn);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#include "network/client/Client.h"
|
||||
#include "network/server/GameServer.h"
|
||||
#include "utils/Config.h"
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
class NetworkManager {
|
||||
public:
|
||||
using ClickEventCallback = std::function<void(int logicalX, int logicalY)>;
|
||||
@@ -47,4 +50,4 @@ private:
|
||||
void startClient();
|
||||
|
||||
void startIOContextLoop();
|
||||
};
|
||||
};
|
||||
|
||||
@@ -202,6 +202,10 @@ void Client::closeConnection() {
|
||||
asio::error_code ec;
|
||||
if (m_socket.is_open()) {
|
||||
m_socket.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||
// 检查错误码
|
||||
if (ec && ec != asio::error::not_connected) {
|
||||
// 处理错误(除了"未连接"之外的错误)
|
||||
}
|
||||
m_socket.close(ec);
|
||||
}
|
||||
m_isWaiting = false;
|
||||
@@ -218,4 +222,4 @@ void Client::attemptReconnect() {
|
||||
timer.async_wait([this, self](const asio::error_code& /*ec*/) {
|
||||
connect(m_host, m_port, m_isHost);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
void sentClickPosition(const NetData& data, bool isChangeTurn = false);
|
||||
|
||||
|
||||
void closeConnection();
|
||||
|
||||
|
||||
private:
|
||||
@@ -48,6 +49,5 @@ private:
|
||||
void waitForOpponent();
|
||||
void stopWaiting(); // 停止等待
|
||||
|
||||
void closeConnection();
|
||||
void attemptReconnect(); // 尝试重新连接
|
||||
};
|
||||
};
|
||||
|
||||
@@ -132,6 +132,10 @@ void GameServer::forwardMoves() {
|
||||
}
|
||||
|
||||
void GameServer::listenPlayer(asio::ip::tcp::socket& fromPlayer, asio::ip::tcp::socket& toPlayer) {
|
||||
// 检查 socket 是否还开着
|
||||
if (!fromPlayer.is_open() || !toPlayer.is_open()) {
|
||||
return;
|
||||
}
|
||||
auto self = shared_from_this();
|
||||
|
||||
fromPlayer.async_read_some(
|
||||
@@ -153,4 +157,30 @@ void GameServer::listenPlayer(asio::ip::tcp::socket& fromPlayer, asio::ip::tcp::
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void GameServer::stop() {
|
||||
std::cout << "GameServer stopping...\n";
|
||||
|
||||
// 关闭 socket,这会导致所有 async_read_some 立即返回错误
|
||||
asio::error_code ec;
|
||||
|
||||
if (m_player1.is_open()) {
|
||||
m_player1.cancel(ec); // 取消所有异步操作
|
||||
m_player1.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||
m_player1.close(ec);
|
||||
}
|
||||
|
||||
if (m_player2.is_open()) {
|
||||
m_player2.cancel(ec);
|
||||
m_player2.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||
m_player2.close(ec);
|
||||
}
|
||||
|
||||
if (m_acceptor.is_open()) {
|
||||
m_acceptor.cancel(ec);
|
||||
m_acceptor.close(ec);
|
||||
}
|
||||
|
||||
std::cout << "GameServer stopped\n";
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ public:
|
||||
~GameServer() = default;
|
||||
|
||||
void startServer( int port);
|
||||
|
||||
void stop();
|
||||
private:
|
||||
asio::io_context& m_ioContext;
|
||||
//std::unique_ptr<asio::ip::tcp::acceptor> m_acceptor;
|
||||
@@ -27,4 +27,4 @@ private:
|
||||
void forwardMoves();
|
||||
|
||||
void listenPlayer(asio::ip::tcp::socket& fromPlayer, asio::ip::tcp::socket& toPlayer);
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user