using System.Collections.Concurrent; using ServerCommon; using ServerCore; namespace GameServer; public class P2PDataWriteState : P2PDataLogStateBase { private ConcurrentDictionary m_all_user_p2p_packet_infos = new(); private CancellationTokenSource m_cancel_token = new(); public DateTime m_last_check_time { get; set; } = DateTimeHelper.Current; readonly int m_record_check_time_min = 1; private PeriodicTaskTimer? m_task_nullable = null; public P2PDataWriteState() : base(true) { } public override void enter() { try { m_cancel_token = new(); m_task_nullable = new PeriodicTaskTimer( GetType().Name, Constant.P2P_PACKET_DATA_CHECK_INTERVAL_MSEC, m_cancel_token, onTaskTick); Log.getLogger().debug("activeMonitoring task created"); } catch(Exception e) { var err_msg = $"Exception !!!, new PeriodicTaskTimer() : exception:{e}"; Log.getLogger().error(err_msg); } } public override async Task update() { //if (m_check_active == false) return; Log.getLogger().debug("p2p monitoring update start"); var users = GameServerApp.getServerLogic().getPlayerManager().getUsers(); foreach (var player in users.Values) { if (player is null) continue; var user_create_or_load_action = player.getEntityAction(); if (false == user_create_or_load_action.isCompletedLoadUser()) { continue; } dataAccumulate(player); } recordDataTotalInfo(); //더이상 패킷이 들어오지 않는 데이터는 삭제 처리 deleteOldData(); await dataAccumulateStateCheck(); Log.getLogger().debug("p2p monitoring update done"); } public override async void exit() { try { if (m_cancel_token != null && !m_cancel_token.IsCancellationRequested) { m_cancel_token.Cancel(); } if (m_task_nullable != null) { try { await m_task_nullable.getTask(); } catch (Exception ex) { Log.getLogger().warn($"Task 예외 발생 (무시됨): {ex}"); } m_task_nullable = null; } m_cancel_token?.Dispose(); //m_cancel_token = null; } catch (Exception e) { Log.getLogger().error($"Exception !!!, stopTaskSafelyAsync() : exception:{e}"); } ServerBase.Monitor.It.setReceivedP2PDataInfo(); Log.getLogger().debug("p2p monitoring exit"); } private async Task dataAccumulateStateCheck() { if (m_all_user_p2p_packet_infos.Keys.Count == 0) { await P2PDataLogManager.It.inactiveMonitoring(); Log.getLogger().debug("p2p incactive monitoring"); } } private async Task onTaskTick() { await update(); } public void deleteOldData() { var now = DateTimeHelper.Current; var delete_users = new List(); foreach (var infos in m_all_user_p2p_packet_infos) { var user_guid = infos.Key; var info = infos.Value; var player_manager = GameServerApp.getServerLogic().getPlayerManager(); if (player_manager.tryGetUserByPrimaryKey(user_guid, out var found_user) == false) continue; var p2p_data_action = found_user.getEntityAction(); if (p2p_data_action is null) { m_all_user_p2p_packet_infos.TryRemove(user_guid, out _); continue; } var elapsed_update_time = p2p_data_action.m_last_update_time.AddMinutes(m_record_check_time_min); if (elapsed_update_time < now) { delete_users.Add(user_guid); } } foreach (var user_guid in delete_users) { m_all_user_p2p_packet_infos.TryRemove(user_guid, out _); Log.getLogger().debug($"delete old p2p packet data userGuid : {user_guid}"); } } public void dataAccumulate(Player player) { if (false == m_all_user_p2p_packet_infos.TryGetValue(player.getUserGuid(), out var info_log)) { info_log = new P2PDataInfoLog(); m_all_user_p2p_packet_infos.TryAdd(player.getUserGuid(), info_log); } var p2p_data_action = player.getEntityAction(); var now = DateTimeHelper.Current; foreach (var data in p2p_data_action.m_data) { var id = data.Key; var packet_count = data.Value.m_packet_count; var packet_size = data.Value.m_total_packet_size; if (packet_count == info_log.m_total_packet_count) continue; info_log.m_total_packet_count = packet_count; info_log.m_total_packet_size = packet_size; info_log.m_last_recorded_time = now; m_last_check_time = now; } } public void recordDataTotalInfo() { var user_count = m_all_user_p2p_packet_infos.Keys.Count; long total_count = 0; long total_size = 0; foreach (var info in m_all_user_p2p_packet_infos.Values) { total_count += info.m_total_packet_count; total_size += info.m_total_packet_size; } ServerBase.Monitor.It.setReceivedP2PDataInfo(total_size, total_count, user_count); Log.getLogger().debug($"recordDataTotalInfo data send total_size : {total_size}, total_count : {total_count}, user_count : {user_count}"); } }