添加连接管理的互斥锁,增强多线程环境下的连接安全性;更新TCPClient以支持断开回调
This commit is contained in:
@@ -48,6 +48,7 @@ int g_currentVirtualPort = 0;
|
||||
std::vector<HSteamNetConnection> connections;
|
||||
std::map<HSteamNetConnection, TCPClient*> clientMap;
|
||||
std::mutex clientMutex;
|
||||
std::mutex connectionsMutex; // Add mutex for connections
|
||||
int localPort = 0;
|
||||
bool g_isHost = false;
|
||||
bool g_isClient = false;
|
||||
@@ -73,7 +74,10 @@ void OnSteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t
|
||||
{
|
||||
// Incoming connection, accept it
|
||||
SteamNetworkingSockets()->AcceptConnection(pInfo->m_hConn);
|
||||
{
|
||||
std::lock_guard<std::mutex> lockConn(connectionsMutex);
|
||||
connections.push_back(pInfo->m_hConn);
|
||||
}
|
||||
g_hConnection = pInfo->m_hConn; // Keep for backward compatibility if needed
|
||||
g_isConnected = true;
|
||||
std::cout << "Accepted incoming connection from " << pInfo->m_info.m_identityRemote.GetSteamID().ConvertToUint64() << std::endl;
|
||||
@@ -115,6 +119,8 @@ void OnSteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t
|
||||
g_isConnected = false;
|
||||
g_hConnection = k_HSteamNetConnection_Invalid;
|
||||
// Remove from connections
|
||||
{
|
||||
std::lock_guard<std::mutex> lockConn(connectionsMutex);
|
||||
auto it = connections.begin();
|
||||
while (it != connections.end()) {
|
||||
if (*it == pInfo->m_hConn) {
|
||||
@@ -123,6 +129,7 @@ void OnSteamNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove from userMap
|
||||
userMap.erase(pInfo->m_hConn);
|
||||
// Cleanup TCP Client
|
||||
@@ -198,7 +205,7 @@ int main() {
|
||||
boost::asio::io_context io_context;
|
||||
|
||||
// Create Steam Message Handler
|
||||
SteamMessageHandler messageHandler(io_context, m_pInterface, connections, clientMap, clientMutex, server, g_isHost, localPort);
|
||||
SteamMessageHandler messageHandler(io_context, m_pInterface, connections, clientMap, clientMutex, connectionsMutex, server, g_isHost, localPort);
|
||||
|
||||
// Initialize GLFW
|
||||
if (!glfwInit()) {
|
||||
@@ -344,6 +351,7 @@ int main() {
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(clientMutex);
|
||||
std::lock_guard<std::mutex> lockConn(connectionsMutex);
|
||||
ImGui::Text("连接的好友: %d", (int)connections.size());
|
||||
ImGui::Text("活跃的TCP客户端: %d", (int)clientMap.size());
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
const char* CONTROL_PREFIX = "CONTROL:";
|
||||
const size_t CONTROL_PREFIX_LEN = 8;
|
||||
|
||||
SteamMessageHandler::SteamMessageHandler(boost::asio::io_context& io_context, ISteamNetworkingSockets* interface, std::vector<HSteamNetConnection>& connections, std::map<HSteamNetConnection, TCPClient*>& clientMap, std::mutex& clientMutex, std::unique_ptr<TCPServer>& server, bool& g_isHost, int& localPort)
|
||||
: io_context_(io_context), m_pInterface_(interface), connections_(connections), clientMap_(clientMap), clientMutex_(clientMutex), server_(server), g_isHost_(g_isHost), localPort_(localPort), running_(false) {}
|
||||
SteamMessageHandler::SteamMessageHandler(boost::asio::io_context& io_context, ISteamNetworkingSockets* interface, std::vector<HSteamNetConnection>& connections, std::map<HSteamNetConnection, TCPClient*>& clientMap, std::mutex& clientMutex, std::mutex& connectionsMutex, std::unique_ptr<TCPServer>& server, bool& g_isHost, int& localPort)
|
||||
: io_context_(io_context), m_pInterface_(interface), connections_(connections), clientMap_(clientMap), clientMutex_(clientMutex), connectionsMutex_(connectionsMutex), server_(server), g_isHost_(g_isHost), localPort_(localPort), running_(false) {}
|
||||
|
||||
SteamMessageHandler::~SteamMessageHandler() {
|
||||
stop();
|
||||
@@ -48,8 +48,13 @@ void SteamMessageHandler::run() {
|
||||
}
|
||||
|
||||
void SteamMessageHandler::pollMessages() {
|
||||
std::vector<HSteamNetConnection> currentConnections;
|
||||
{
|
||||
std::lock_guard<std::mutex> lockConn(connectionsMutex_);
|
||||
currentConnections = connections_;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(clientMutex_);
|
||||
for (auto conn : connections_) {
|
||||
for (auto conn : currentConnections) {
|
||||
ISteamNetworkingMessage* pIncomingMsgs[10];
|
||||
int numMsgs = m_pInterface_->ReceiveMessagesOnConnection(conn, pIncomingMsgs, 10);
|
||||
for (int i = 0; i < numMsgs; ++i) {
|
||||
@@ -72,6 +77,11 @@ void SteamMessageHandler::pollMessages() {
|
||||
std::lock_guard<std::mutex> lock(clientMutex_);
|
||||
m_pInterface_->SendMessageToConnection(conn, data, size, k_nSteamNetworkingSend_Reliable, nullptr);
|
||||
});
|
||||
client->setDisconnectCallback([conn, this]() {
|
||||
std::lock_guard<std::mutex> lock(clientMutex_);
|
||||
m_pInterface_->CloseConnection(conn, 0, nullptr, false);
|
||||
std::cout << "Closed Steam connection due to TCP client disconnect" << std::endl;
|
||||
});
|
||||
clientMap_[conn] = client;
|
||||
std::cout << "Created TCP Client for connection on first message" << std::endl;
|
||||
} else {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
class SteamMessageHandler {
|
||||
public:
|
||||
SteamMessageHandler(boost::asio::io_context& io_context, ISteamNetworkingSockets* interface, std::vector<HSteamNetConnection>& connections, std::map<HSteamNetConnection, TCPClient*>& clientMap, std::mutex& clientMutex, std::unique_ptr<TCPServer>& server, bool& g_isHost, int& localPort);
|
||||
SteamMessageHandler(boost::asio::io_context& io_context, ISteamNetworkingSockets* interface, std::vector<HSteamNetConnection>& connections, std::map<HSteamNetConnection, TCPClient*>& clientMap, std::mutex& clientMutex, std::mutex& connectionsMutex, std::unique_ptr<TCPServer>& server, bool& g_isHost, int& localPort);
|
||||
~SteamMessageHandler();
|
||||
|
||||
void start();
|
||||
@@ -28,6 +28,7 @@ private:
|
||||
std::vector<HSteamNetConnection>& connections_;
|
||||
std::map<HSteamNetConnection, TCPClient*>& clientMap_;
|
||||
std::mutex& clientMutex_;
|
||||
std::mutex& connectionsMutex_;
|
||||
std::unique_ptr<TCPServer>& server_;
|
||||
bool& g_isHost_;
|
||||
int& localPort_;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "tcp_client.h"
|
||||
#include <iostream>
|
||||
|
||||
TCPClient::TCPClient(const std::string& host, int port) : host_(host), port_(port), connected_(false), socket_(std::make_shared<tcp::socket>(io_context_)), work_(boost::asio::make_work_guard(io_context_)), buffer_(1024) {}
|
||||
TCPClient::TCPClient(const std::string& host, int port) : host_(host), port_(port), connected_(false), disconnected_(false), socket_(std::make_shared<tcp::socket>(io_context_)), work_(boost::asio::make_work_guard(io_context_)), buffer_(1024) {}
|
||||
|
||||
TCPClient::~TCPClient() { disconnect(); }
|
||||
|
||||
@@ -26,6 +26,11 @@ bool TCPClient::connect() {
|
||||
}
|
||||
|
||||
void TCPClient::disconnect() {
|
||||
if (disconnected_) return;
|
||||
disconnected_ = true;
|
||||
if (disconnectCallback_) {
|
||||
disconnectCallback_();
|
||||
}
|
||||
connected_ = false;
|
||||
io_context_.stop();
|
||||
if (clientThread_.joinable()) {
|
||||
@@ -59,6 +64,10 @@ void TCPClient::setReceiveCallback(std::function<void(const char*, size_t)> call
|
||||
receiveCallbackBytes_ = callback;
|
||||
}
|
||||
|
||||
void TCPClient::setDisconnectCallback(std::function<void()> callback) {
|
||||
disconnectCallback_ = callback;
|
||||
}
|
||||
|
||||
void TCPClient::start_read() {
|
||||
socket_->async_read_some(boost::asio::buffer(buffer_), [this](const boost::system::error_code& error, std::size_t bytes_transferred) {
|
||||
handle_read(error, bytes_transferred);
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
void send(const char* data, size_t size);
|
||||
void setReceiveCallback(std::function<void(const std::string&)> callback);
|
||||
void setReceiveCallback(std::function<void(const char*, size_t)> callback);
|
||||
void setDisconnectCallback(std::function<void()> callback);
|
||||
|
||||
private:
|
||||
void start_read();
|
||||
@@ -29,6 +30,7 @@ private:
|
||||
std::string host_;
|
||||
int port_;
|
||||
bool connected_;
|
||||
bool disconnected_;
|
||||
boost::asio::io_context io_context_;
|
||||
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work_;
|
||||
std::shared_ptr<tcp::socket> socket_;
|
||||
@@ -36,5 +38,6 @@ private:
|
||||
std::mutex socketMutex_;
|
||||
std::function<void(const std::string&)> receiveCallback_;
|
||||
std::function<void(const char*, size_t)> receiveCallbackBytes_;
|
||||
std::function<void()> disconnectCallback_;
|
||||
std::vector<char> buffer_;
|
||||
};
|
||||
Reference in New Issue
Block a user