2024-12-12 22:43:24 +08:00
|
|
|
#include "server.h"
|
2025-03-01 03:49:40 +08:00
|
|
|
|
2024-12-13 23:03:12 +08:00
|
|
|
#include <of_str.h>
|
2024-12-17 08:57:43 +08:00
|
|
|
#include <of_util.h>
|
2025-02-16 14:58:03 +08:00
|
|
|
#include <version.h>
|
2024-12-13 23:03:12 +08:00
|
|
|
|
|
|
|
using namespace ofen;
|
2025-01-14 00:09:39 +08:00
|
|
|
constexpr int check_idle_percycle = 1000 * 30; // 毫秒
|
|
|
|
constexpr int remove_after_time = 60; // 秒
|
2025-03-01 03:49:40 +08:00
|
|
|
CTcpServer::CTcpServer(asio::io_context& io_context) : io_context_(io_context), acceptor_(io_context)
|
2024-12-12 23:11:55 +08:00
|
|
|
{
|
2024-12-13 12:35:08 +08:00
|
|
|
th_run_ = true;
|
2025-01-06 14:39:53 +08:00
|
|
|
sleep_.set_timeout(check_idle_percycle);
|
2024-12-12 23:11:55 +08:00
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
|
2024-12-12 23:11:55 +08:00
|
|
|
CTcpServer::~CTcpServer()
|
2024-12-12 22:43:24 +08:00
|
|
|
{
|
2024-12-13 12:35:08 +08:00
|
|
|
th_run_ = false;
|
2025-01-06 14:39:53 +08:00
|
|
|
sleep_.contiune();
|
|
|
|
if (th_monitor_idle_.joinable()) {
|
|
|
|
th_monitor_idle_.join();
|
|
|
|
}
|
2024-12-12 22:43:24 +08:00
|
|
|
}
|
|
|
|
|
2024-12-13 12:35:08 +08:00
|
|
|
bool CTcpServer::start(unsigned short port)
|
2024-12-12 22:43:24 +08:00
|
|
|
{
|
2025-01-12 21:27:44 +08:00
|
|
|
asio::ip::tcp::resolver resolver(io_context_);
|
|
|
|
asio::ip::tcp::resolver::query query(asio::ip::host_name(), "");
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGI("version: {}", VERSION_NUM);
|
|
|
|
TLOGI("opensource: {}", VERSION_URL);
|
2025-02-05 11:00:05 +08:00
|
|
|
try {
|
|
|
|
auto it = resolver.resolve(query);
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGD("Here are the local IP addresses you may use.");
|
|
|
|
TLOGD("===========================================");
|
2025-02-05 11:00:05 +08:00
|
|
|
int i = 1;
|
2025-02-06 09:37:24 +08:00
|
|
|
while (!it.empty()) {
|
2025-02-05 11:00:05 +08:00
|
|
|
asio::ip::address addr = it->endpoint().address();
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGI("({}){}", i, addr.to_string());
|
2025-02-05 11:00:05 +08:00
|
|
|
++it;
|
|
|
|
++i;
|
|
|
|
}
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGD("===========================================");
|
2025-02-05 11:00:05 +08:00
|
|
|
} catch (const std::exception& e) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGW("{}", e.what());
|
|
|
|
TLOGI("will not show local IP.");
|
2025-01-12 21:27:44 +08:00
|
|
|
}
|
|
|
|
|
2024-12-12 23:11:55 +08:00
|
|
|
asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
|
|
|
|
try {
|
|
|
|
acceptor_.open(endpoint.protocol());
|
2025-04-07 16:41:28 +08:00
|
|
|
// acceptor_.set_option(asio::socket_base::reuse_address(true));
|
2024-12-12 23:11:55 +08:00
|
|
|
acceptor_.bind(endpoint);
|
|
|
|
acceptor_.listen();
|
|
|
|
} catch (const asio::system_error& e) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGE("Failed to bind to {}: {}", endpoint.address().to_string(), e.what());
|
2024-12-12 23:11:55 +08:00
|
|
|
return false;
|
|
|
|
}
|
2024-12-14 16:20:25 +08:00
|
|
|
auto bound_endpoint = acceptor_.local_endpoint();
|
|
|
|
server_ip_ = bound_endpoint.address().to_string() + ":" + std::to_string(bound_endpoint.port());
|
2024-12-13 12:35:08 +08:00
|
|
|
accept_client();
|
2025-01-06 14:39:53 +08:00
|
|
|
th_monitor_idle_ = std::thread([this]() { monitor_idle(); });
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGI("Server started on port {}", port);
|
2024-12-12 23:11:55 +08:00
|
|
|
return true;
|
2024-12-12 22:43:24 +08:00
|
|
|
}
|
|
|
|
|
2024-12-13 12:35:08 +08:00
|
|
|
void CTcpServer::stop()
|
2024-12-12 22:43:24 +08:00
|
|
|
{
|
2024-12-12 23:11:55 +08:00
|
|
|
acceptor_.close();
|
2025-01-14 00:09:39 +08:00
|
|
|
std::unique_lock<std::shared_mutex> lock(cli_mut_);
|
2024-12-12 23:11:55 +08:00
|
|
|
for (auto& [key, thread] : client_threads_) {
|
|
|
|
if (thread.joinable()) {
|
|
|
|
thread.join();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
client_threads_.clear();
|
|
|
|
}
|
|
|
|
|
2025-04-07 17:28:50 +08:00
|
|
|
void CTcpServer::get_client_list(CMessageInfo& msg_info)
|
2024-12-13 12:35:08 +08:00
|
|
|
{
|
2025-04-07 23:12:27 +08:00
|
|
|
struct TmpInfo {
|
|
|
|
std::string id;
|
|
|
|
std::string online_time;
|
|
|
|
std::string uuid;
|
|
|
|
std::string task;
|
|
|
|
uint64_t timestamp;
|
|
|
|
};
|
|
|
|
std::vector<TmpInfo> vec;
|
2024-12-13 12:35:08 +08:00
|
|
|
std::string msg;
|
2025-04-07 23:12:27 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
std::shared_lock<std::shared_mutex> lock(cli_mut_);
|
|
|
|
for (const auto& item : client_map_) {
|
|
|
|
TmpInfo tmp;
|
|
|
|
tmp.id = item.first;
|
|
|
|
tmp.online_time = item.second->online_time_;
|
|
|
|
tmp.timestamp = item.second->timestamp;
|
|
|
|
tmp.uuid = item.second->uuid;
|
|
|
|
tmp.task = item.second->task_;
|
|
|
|
vec.push_back(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 排序 vec 根据 client->timestamp
|
|
|
|
std::sort(vec.begin(), vec.end(),
|
|
|
|
[](const TmpInfo& a, const TmpInfo& b) { return a.timestamp < b.timestamp; });
|
|
|
|
|
2024-12-13 23:03:12 +08:00
|
|
|
int index = 1;
|
2024-12-13 12:35:08 +08:00
|
|
|
for (const auto& item : vec) {
|
2025-04-07 23:12:27 +08:00
|
|
|
msg.append(fmt::format("[{}][{}][{}][{}]", index, item.id, item.online_time, item.uuid));
|
|
|
|
auto files = COfStr::split(item.task, "|");
|
2024-12-13 23:03:12 +08:00
|
|
|
for (const auto& file : files) {
|
|
|
|
msg.append("\n" + file);
|
2024-12-13 12:35:08 +08:00
|
|
|
}
|
2024-12-14 16:20:25 +08:00
|
|
|
msg.append("\n");
|
|
|
|
++index;
|
2024-12-13 12:35:08 +08:00
|
|
|
}
|
2025-04-07 17:28:50 +08:00
|
|
|
msg_info.str = msg;
|
2024-12-13 12:35:08 +08:00
|
|
|
}
|
|
|
|
|
2024-12-18 16:55:32 +08:00
|
|
|
void CTcpServer::trans_data(CFrameBuffer* buf)
|
2024-12-13 12:35:08 +08:00
|
|
|
{
|
2024-12-18 16:55:32 +08:00
|
|
|
std::shared_ptr<ClientCache> fcli = nullptr;
|
|
|
|
std::shared_ptr<ClientCache> tcli = nullptr;
|
|
|
|
|
|
|
|
{
|
2025-01-14 00:09:39 +08:00
|
|
|
std::shared_lock<std::shared_mutex> lock(cli_mut_);
|
2024-12-18 16:55:32 +08:00
|
|
|
if (client_map_.count(buf->fid_)) {
|
|
|
|
fcli = client_map_[buf->fid_];
|
2024-12-13 12:35:08 +08:00
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
if (client_map_.count(buf->tid_)) {
|
|
|
|
tcli = client_map_[buf->tid_];
|
2024-12-13 12:39:34 +08:00
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
}
|
2024-12-17 08:57:43 +08:00
|
|
|
|
2024-12-18 16:55:32 +08:00
|
|
|
switch (buf->type_) {
|
|
|
|
case TYPE_GET_LIST: {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGI("[{}] GetList.", buf->fid_);
|
2025-04-08 22:09:03 +08:00
|
|
|
CMessageInfo msg_info(server_ip_);
|
2025-04-07 17:28:50 +08:00
|
|
|
get_client_list(msg_info);
|
2025-04-08 22:09:03 +08:00
|
|
|
buf->fid_ = server_ip_;
|
2025-04-07 17:28:50 +08:00
|
|
|
serialize(msg_info, &buf->data_, buf->len_);
|
2024-12-18 16:55:32 +08:00
|
|
|
if (fcli && !send_frame(fcli->socket_, buf)) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGE("GetList send failed.");
|
2024-12-14 11:57:33 +08:00
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TYPE_UP_LIST: {
|
2025-04-08 20:01:09 +08:00
|
|
|
CMessageInfo msg_info(buf->fid_);
|
2025-04-07 17:28:50 +08:00
|
|
|
if (!deserialize(buf->data_, buf->len_, msg_info)) {
|
|
|
|
TLOGE("{} GetList deserialize failed.", __LINE__);
|
|
|
|
break;
|
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
if (fcli) {
|
2025-04-07 17:28:50 +08:00
|
|
|
fcli->task_ = msg_info.str;
|
|
|
|
fcli->uuid = msg_info.uuid;
|
2024-12-24 09:46:24 +08:00
|
|
|
fcli->task_time_ = OfUtil::now_time();
|
2024-12-14 11:57:33 +08:00
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TYPE_CANCEL_LIST: {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGI("[{}] Cancle Task.", buf->fid_);
|
2024-12-18 16:55:32 +08:00
|
|
|
if (fcli) {
|
|
|
|
fcli->task_.clear();
|
2024-12-24 09:46:24 +08:00
|
|
|
fcli->task_time_.clear();
|
2024-12-14 11:57:33 +08:00
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
break;
|
|
|
|
}
|
2024-12-24 09:46:24 +08:00
|
|
|
case TYPE_GET_ID: {
|
|
|
|
buf->tid_ = buf->fid_;
|
|
|
|
send_frame(fcli->socket_, buf);
|
|
|
|
break;
|
|
|
|
}
|
2024-12-18 22:04:54 +08:00
|
|
|
case TYPE_JUDGE_ACTIVE: {
|
|
|
|
if (fcli && tcli) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (fcli && tcli == nullptr) {
|
|
|
|
buf->type_ = TYPE_OFFLINE;
|
|
|
|
std::swap(buf->fid_, buf->tid_);
|
|
|
|
send_frame(fcli->socket_, buf);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2024-12-21 23:24:18 +08:00
|
|
|
default:
|
2024-12-19 15:54:42 +08:00
|
|
|
if (check_double(buf, fcli, tcli) && tcli && !send_frame(tcli->socket_, buf)) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGE("Send from {} to {} failed Or One Offline.", buf->fid_, buf->tid_);
|
2024-12-13 12:35:08 +08:00
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-19 15:54:42 +08:00
|
|
|
bool CTcpServer::check_double(CFrameBuffer* buf, std::shared_ptr<ClientCache>& fcli,
|
|
|
|
std::shared_ptr<ClientCache>& tcli)
|
2024-12-18 16:55:32 +08:00
|
|
|
{
|
2025-01-14 00:09:39 +08:00
|
|
|
std::shared_lock<std::shared_mutex> lock(cli_mut_);
|
2024-12-19 15:54:42 +08:00
|
|
|
if (client_map_.count(buf->fid_)) {
|
|
|
|
fcli = client_map_[buf->fid_];
|
|
|
|
}
|
|
|
|
if (client_map_.count(buf->tid_)) {
|
|
|
|
tcli = client_map_[buf->tid_];
|
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
if (fcli == nullptr && tcli) {
|
|
|
|
buf->type_ = TYPE_OFFLINE;
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGW("A Notic {} That {} Offline.", buf->tid_, buf->fid_);
|
2024-12-18 16:55:32 +08:00
|
|
|
send_frame(tcli->socket_, buf);
|
|
|
|
return false;
|
2024-12-12 22:43:24 +08:00
|
|
|
}
|
2024-12-18 16:55:32 +08:00
|
|
|
if (tcli == nullptr && fcli) {
|
|
|
|
std::swap(buf->fid_, buf->tid_);
|
|
|
|
buf->type_ = TYPE_OFFLINE;
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGW("B Notic {} That {} Offline.", buf->tid_, buf->fid_);
|
2024-12-18 16:55:32 +08:00
|
|
|
send_frame(fcli->socket_, buf);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (tcli == nullptr && fcli == nullptr) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGW("Both Offline.", buf->fid_, buf->tid_);
|
2024-12-18 16:55:32 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2024-12-12 22:43:24 +08:00
|
|
|
}
|
|
|
|
|
2024-12-13 12:35:08 +08:00
|
|
|
void CTcpServer::accept_client()
|
2024-12-12 22:43:24 +08:00
|
|
|
{
|
2024-12-12 23:11:55 +08:00
|
|
|
auto socket = std::make_shared<asio::ip::tcp::socket>(io_context_);
|
|
|
|
acceptor_.async_accept(*socket, [this, socket](const asio::error_code& error) {
|
|
|
|
if (!error) {
|
|
|
|
auto endpoint = socket->remote_endpoint();
|
|
|
|
std::string client_key = endpoint.address().to_string() + ":" + std::to_string(endpoint.port());
|
|
|
|
|
2024-12-20 13:22:28 +08:00
|
|
|
bool can = false;
|
2024-12-12 23:11:55 +08:00
|
|
|
{
|
2025-01-14 00:09:39 +08:00
|
|
|
std::unique_lock<std::shared_mutex> lock(cli_mut_);
|
2024-12-20 13:22:28 +08:00
|
|
|
if (client_map_.size() >= 100) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGI("Max client connections reached. Closing connection from {}", client_key);
|
2024-12-20 13:22:28 +08:00
|
|
|
socket->close();
|
|
|
|
} else {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGI("New connection from {}", client_key);
|
2024-12-20 13:22:28 +08:00
|
|
|
auto cache = std::make_shared<ClientCache>();
|
|
|
|
cache->socket_ = socket;
|
2024-12-24 09:46:24 +08:00
|
|
|
cache->online_time_ = OfUtil::now_time();
|
2025-04-07 23:12:27 +08:00
|
|
|
cache->timestamp = OfUtil::get_timestamp_ms();
|
2025-01-06 14:39:53 +08:00
|
|
|
cache->last_active_time_ = std::chrono::high_resolution_clock::now();
|
2024-12-20 13:22:28 +08:00
|
|
|
client_map_[client_key] = cache;
|
|
|
|
can = true;
|
|
|
|
}
|
|
|
|
}
|
2025-02-06 09:37:24 +08:00
|
|
|
if (!can) {
|
2024-12-20 13:22:28 +08:00
|
|
|
std::this_thread::sleep_for(std::chrono::minutes(1));
|
|
|
|
} else {
|
|
|
|
client_threads_[client_key] = std::thread(&CTcpServer::th_client, this, socket, client_key);
|
2024-12-12 23:11:55 +08:00
|
|
|
}
|
|
|
|
}
|
2024-12-13 12:35:08 +08:00
|
|
|
accept_client();
|
2024-12-12 23:11:55 +08:00
|
|
|
});
|
2024-12-12 22:43:24 +08:00
|
|
|
}
|
2024-12-12 23:11:55 +08:00
|
|
|
|
2025-02-06 09:37:24 +08:00
|
|
|
void CTcpServer::th_client(const std::shared_ptr<asio::ip::tcp::socket>& socket,
|
|
|
|
const std::string& client_key)
|
2024-12-12 23:11:55 +08:00
|
|
|
{
|
2024-12-13 12:35:08 +08:00
|
|
|
std::shared_ptr<int> deleter(new int(0), [&](int* p) {
|
2025-01-14 00:09:39 +08:00
|
|
|
std::unique_lock<std::shared_mutex> lock(cli_mut_);
|
2024-12-13 12:35:08 +08:00
|
|
|
delete p;
|
|
|
|
client_map_.erase(client_key);
|
|
|
|
if (client_threads_.find(client_key) != client_threads_.end()) {
|
|
|
|
client_threads_.at(client_key).detach();
|
|
|
|
client_threads_.erase(client_key);
|
|
|
|
}
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGW("th_client deleter client {} exit.", client_key);
|
2024-12-13 12:35:08 +08:00
|
|
|
});
|
|
|
|
|
2024-12-12 23:11:55 +08:00
|
|
|
try {
|
2024-12-13 12:35:08 +08:00
|
|
|
std::shared_ptr<ClientCache> cache = nullptr;
|
|
|
|
|
|
|
|
{
|
2025-01-14 00:09:39 +08:00
|
|
|
std::shared_lock<std::shared_mutex> lock(cli_mut_);
|
2024-12-13 12:35:08 +08:00
|
|
|
if (!client_map_.count(client_key)) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGE("Not Find Client{} in cache.", client_key);
|
2024-12-13 12:35:08 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
cache = client_map_[client_key];
|
|
|
|
}
|
|
|
|
|
2024-12-12 23:11:55 +08:00
|
|
|
while (true) {
|
|
|
|
asio::error_code error;
|
2024-12-13 12:35:08 +08:00
|
|
|
size_t length = socket->read_some(asio::buffer(cache->tmp_buf_), error);
|
2024-12-12 23:11:55 +08:00
|
|
|
if (error == asio::error::eof) {
|
|
|
|
break;
|
|
|
|
} else if (error) {
|
|
|
|
throw asio::system_error(error);
|
|
|
|
}
|
|
|
|
|
2025-02-06 09:37:24 +08:00
|
|
|
cache->buffer_.push(cache->tmp_buf_.data(), static_cast<int>(length));
|
2024-12-18 12:55:00 +08:00
|
|
|
while (true) {
|
|
|
|
auto* frame = CTransProtocal::parse(cache->buffer_);
|
|
|
|
if (frame) {
|
2024-12-18 13:55:56 +08:00
|
|
|
if (frame->type_ == TYPE_HEARTS) {
|
2025-01-14 00:09:39 +08:00
|
|
|
std::unique_lock<std::shared_mutex> lock(cli_mut_);
|
2025-01-06 14:39:53 +08:00
|
|
|
if (client_map_.count(client_key)) {
|
|
|
|
auto& cli = client_map_[client_key];
|
|
|
|
cli->last_active_time_ = std::chrono::high_resolution_clock::now();
|
|
|
|
}
|
2024-12-18 13:55:56 +08:00
|
|
|
delete frame;
|
|
|
|
continue;
|
|
|
|
}
|
2025-04-07 17:28:50 +08:00
|
|
|
if (frame->type_ == TYPE_GET_ID) {
|
2025-04-08 20:01:09 +08:00
|
|
|
CMessageInfo msg_info("");
|
2025-04-07 17:28:50 +08:00
|
|
|
if (!deserialize(frame->data_, frame->len_, msg_info)) {
|
|
|
|
TLOGE("{} GetId deserialize failed.", __LINE__);
|
|
|
|
delete frame;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
std::unique_lock<std::shared_mutex> lock(cli_mut_);
|
|
|
|
if (client_map_.count(client_key)) {
|
|
|
|
auto& cli = client_map_[client_key];
|
|
|
|
cli->uuid = msg_info.uuid;
|
|
|
|
}
|
|
|
|
}
|
2024-12-18 12:55:00 +08:00
|
|
|
frame->fid_ = client_key;
|
2024-12-18 16:55:32 +08:00
|
|
|
// 直接转发,不加入缓存。
|
|
|
|
trans_data(frame);
|
|
|
|
delete frame;
|
2024-12-18 12:55:00 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
2024-12-12 23:11:55 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (std::exception& e) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGE("Error with client {}: {}", client_key, e.what());
|
2024-12-12 23:11:55 +08:00
|
|
|
}
|
2024-12-14 11:57:33 +08:00
|
|
|
}
|
|
|
|
|
2025-02-06 09:37:24 +08:00
|
|
|
bool CTcpServer::send_frame(const std::shared_ptr<asio::ip::tcp::socket>& socket, CFrameBuffer* buf)
|
2024-12-14 11:57:33 +08:00
|
|
|
{
|
|
|
|
char* out_buf{};
|
|
|
|
int out_len{};
|
2024-12-14 16:20:25 +08:00
|
|
|
if (buf->fid_.empty()) {
|
|
|
|
buf->fid_ = server_ip_;
|
|
|
|
}
|
|
|
|
|
2024-12-14 11:57:33 +08:00
|
|
|
if (!CTransProtocal::pack(buf, &out_buf, out_len)) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGE("{} pack failed.", __FUNCTION__);
|
2024-12-14 11:57:33 +08:00
|
|
|
return false;
|
|
|
|
}
|
2024-12-19 16:59:50 +08:00
|
|
|
try {
|
|
|
|
if (!socket->send(asio::buffer(out_buf, out_len))) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGE("{} send failed, buf type:{}, fid:{}, tid:{}", __FUNCTION__, static_cast<int>(buf->type_),
|
|
|
|
buf->fid_, buf->tid_);
|
2024-12-19 16:59:50 +08:00
|
|
|
delete[] out_buf;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} catch (const std::exception& e) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGE("send failed, type:{}, fid:{}, tid:{}, mark:{}", static_cast<int>(buf->type_), buf->fid_,
|
2025-02-24 17:43:58 +08:00
|
|
|
buf->tid_, buf->mark_);
|
2024-12-14 11:57:33 +08:00
|
|
|
}
|
2024-12-19 16:59:50 +08:00
|
|
|
|
2024-12-14 11:57:33 +08:00
|
|
|
delete[] out_buf;
|
|
|
|
return true;
|
|
|
|
}
|
2025-01-06 14:39:53 +08:00
|
|
|
|
|
|
|
void CTcpServer::monitor_idle()
|
|
|
|
{
|
|
|
|
while (th_run_) {
|
|
|
|
sleep_.sleep();
|
|
|
|
if (!th_run_) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
std::vector<std::string> remove_vec;
|
2025-01-14 00:09:39 +08:00
|
|
|
std::unique_lock<std::shared_mutex> lock(cli_mut_);
|
2025-01-06 14:39:53 +08:00
|
|
|
for (auto& item : client_map_) {
|
|
|
|
auto now = std::chrono::high_resolution_clock::now();
|
|
|
|
auto duration =
|
|
|
|
std::chrono::duration_cast<std::chrono::seconds>(now - item.second->last_active_time_)
|
|
|
|
.count();
|
|
|
|
if (duration >= remove_after_time) {
|
2025-03-01 03:49:40 +08:00
|
|
|
TLOGW("OnLine Time [{}] sec, Proactively disconnect:{}", duration, item.first);
|
2025-01-06 14:39:53 +08:00
|
|
|
remove_vec.push_back(item.first);
|
|
|
|
item.second->socket_->shutdown(asio::ip::tcp::socket::shutdown_both);
|
|
|
|
item.second->socket_->close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const auto& item : remove_vec) {
|
|
|
|
client_map_.erase(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|