mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-10 14:24:10 +08:00
refactor: improve resource cleanup logic on network battle exit
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
#include "NetworkManager.h"
|
#include "NetworkManager.h"
|
||||||
|
|
||||||
#include "utils/ConfigLoader.h"
|
#include "utils/ConfigLoader.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
NetworkManager::NetworkManager()
|
NetworkManager::NetworkManager()
|
||||||
@@ -9,10 +10,30 @@ NetworkManager::NetworkManager()
|
|||||||
}
|
}
|
||||||
|
|
||||||
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();
|
m_ioContext.stop();
|
||||||
|
|
||||||
|
// 4. 等待线程结束
|
||||||
if (m_ioThread.joinable()) {
|
if (m_ioThread.joinable()) {
|
||||||
m_ioThread.join();
|
m_ioThread.join();
|
||||||
|
std::cout << "Network thread joined\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "NetworkManager destroyed\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkManager::init(NetType type) {
|
void NetworkManager::init(NetType type) {
|
||||||
@@ -101,9 +122,11 @@ void NetworkManager::startClient() {
|
|||||||
}
|
}
|
||||||
std::cout << "start client success\n";
|
std::cout << "start client success\n";
|
||||||
startIOContextLoop();
|
startIOContextLoop();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkManager::startIOContextLoop() {
|
void NetworkManager::startIOContextLoop() {
|
||||||
|
|
||||||
|
|
||||||
m_ioThread = std::thread([this]() {
|
m_ioThread = std::thread([this]() {
|
||||||
try {
|
try {
|
||||||
@@ -136,4 +159,4 @@ void NetworkManager::setIsMyTurn(bool isMyTurn) {
|
|||||||
m_client->setShouldWait(!isMyTurn);
|
m_client->setShouldWait(!isMyTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
#include "network/client/Client.h"
|
#include "network/client/Client.h"
|
||||||
#include "network/server/GameServer.h"
|
#include "network/server/GameServer.h"
|
||||||
#include "utils/Config.h"
|
#include "utils/Config.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
class NetworkManager {
|
class NetworkManager {
|
||||||
public:
|
public:
|
||||||
using ClickEventCallback = std::function<void(int logicalX, int logicalY)>;
|
using ClickEventCallback = std::function<void(int logicalX, int logicalY)>;
|
||||||
@@ -47,4 +50,4 @@ private:
|
|||||||
void startClient();
|
void startClient();
|
||||||
|
|
||||||
void startIOContextLoop();
|
void startIOContextLoop();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -202,6 +202,10 @@ void Client::closeConnection() {
|
|||||||
asio::error_code ec;
|
asio::error_code ec;
|
||||||
if (m_socket.is_open()) {
|
if (m_socket.is_open()) {
|
||||||
m_socket.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
m_socket.shutdown(asio::ip::tcp::socket::shutdown_both, ec);
|
||||||
|
// 检查错误码
|
||||||
|
if (ec && ec != asio::error::not_connected) {
|
||||||
|
// 处理错误(除了"未连接"之外的错误)
|
||||||
|
}
|
||||||
m_socket.close(ec);
|
m_socket.close(ec);
|
||||||
}
|
}
|
||||||
m_isWaiting = false;
|
m_isWaiting = false;
|
||||||
@@ -218,4 +222,4 @@ void Client::attemptReconnect() {
|
|||||||
timer.async_wait([this, self](const asio::error_code& /*ec*/) {
|
timer.async_wait([this, self](const asio::error_code& /*ec*/) {
|
||||||
connect(m_host, m_port, m_isHost);
|
connect(m_host, m_port, m_isHost);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public:
|
|||||||
void sentClickPosition(const NetData& data, bool isChangeTurn = false);
|
void sentClickPosition(const NetData& data, bool isChangeTurn = false);
|
||||||
|
|
||||||
|
|
||||||
|
void closeConnection();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -48,6 +49,5 @@ private:
|
|||||||
void waitForOpponent();
|
void waitForOpponent();
|
||||||
void stopWaiting(); // 停止等待
|
void stopWaiting(); // 停止等待
|
||||||
|
|
||||||
void closeConnection();
|
|
||||||
void attemptReconnect(); // 尝试重新连接
|
void attemptReconnect(); // 尝试重新连接
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ void GameServer::forwardMoves() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameServer::listenPlayer(asio::ip::tcp::socket& fromPlayer, asio::ip::tcp::socket& toPlayer) {
|
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();
|
auto self = shared_from_this();
|
||||||
|
|
||||||
fromPlayer.async_read_some(
|
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;
|
~GameServer() = default;
|
||||||
|
|
||||||
void startServer( int port);
|
void startServer( int port);
|
||||||
|
void stop();
|
||||||
private:
|
private:
|
||||||
asio::io_context& m_ioContext;
|
asio::io_context& m_ioContext;
|
||||||
//std::unique_ptr<asio::ip::tcp::acceptor> m_acceptor;
|
//std::unique_ptr<asio::ip::tcp::acceptor> m_acceptor;
|
||||||
@@ -27,4 +27,4 @@ private:
|
|||||||
void forwardMoves();
|
void forwardMoves();
|
||||||
|
|
||||||
void listenPlayer(asio::ip::tcp::socket& fromPlayer, asio::ip::tcp::socket& toPlayer);
|
void listenPlayer(asio::ip::tcp::socket& fromPlayer, asio::ip::tcp::socket& toPlayer);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user