From 30c46f5c73a46613e58e601e70210e3c650e47c0 Mon Sep 17 00:00:00 2001 From: Blank Date: Fri, 7 Aug 2026 00:01:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(kcp):=20=E9=87=8A=E6=94=BE=20KcpNetWorkChan?= =?UTF-8?q?nel=20=E7=9A=84=20CancellationTokenSource=20=E5=B9=B6=E6=8B=86?= =?UTF-8?q?=E5=88=86=20WriteAsync=20=E6=B6=88=E9=99=A4=20Sonar=20S2930/S37?= =?UTF-8?q?76?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit S2930: 类实现 IDisposable,Close 末尾 Dispose _cancellationTokenSource,新增 Dispose 转发 Close。 S3776: 将 WriteAsync 嵌套 debug 日志分支抽取为 private LogSendDebug,参照兄弟类 BaseNetWorkChannel 同模式。 Linear: GFX-545 --- GameFrameX.NetWork.Kcp/KcpNetWorkChannel.cs | 61 +++++++++++++++------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/GameFrameX.NetWork.Kcp/KcpNetWorkChannel.cs b/GameFrameX.NetWork.Kcp/KcpNetWorkChannel.cs index d52e87fdd..767964ad3 100644 --- a/GameFrameX.NetWork.Kcp/KcpNetWorkChannel.cs +++ b/GameFrameX.NetWork.Kcp/KcpNetWorkChannel.cs @@ -42,7 +42,7 @@ namespace GameFrameX.NetWork.Kcp; /// KCP network channel / KCP 网络通道 /// Implements INetWorkChannel interface /// -public sealed class KcpNetWorkChannel : INetWorkChannel +public sealed class KcpNetWorkChannel : INetWorkChannel, IDisposable { private readonly CancellationTokenSource _cancellationTokenSource = new(); private readonly KcpGameAppSession _gameAppSession; @@ -135,22 +135,8 @@ public async Task WriteAsync(INetworkMessage msg, int errorCode = 0) var actorId = GetData(GlobalConst.ActorIdKey); var messageData = MessageHelper.EncoderHandler.Handler(msg); - - if (Setting.IsDebug && Setting.IsDebugSend) - { - if (msg is IHeartBeatMessage) - { - if (Setting.IsDebugSendHeartBeat) - { - LogHelper.Debug("Send HeartBeat Message:{actorId} {message}", actorId, LocalizationService.GetString(Keys.NetWork.MessageSent, msg.ToFormatMessageString(actorId))); - } - } - else - { - var responseErrorCode = msg is IResponseMessage respMsg2 ? respMsg2.ErrorCode : 0; - LogHelper.Debug("Send Message:{actorId} {errorCode} {message}", actorId, responseErrorCode, LocalizationService.GetString(Keys.NetWork.MessageSent, msg.ToFormatMessageString(actorId))); - } - } + var responseErrorCode = msg is IResponseMessage responseMessage ? responseMessage.ErrorCode : 0; + LogSendDebug(msg, actorId, responseErrorCode); if (!KcpSession.IsConnected) { @@ -173,6 +159,35 @@ public async Task WriteAsync(INetworkMessage msg, int errorCode = 0) } } + /// + /// Log the outgoing message when send debugging is enabled / 在开启发送调试时记录发送消息日志 + /// + /// + /// Heartbeat messages are additionally gated by the heartbeat debug flag. Extracted from WriteAsync to reduce cognitive complexity. + /// + /// Network message / 网络消息 + /// Actor id / 角色 Id + /// Response error code / 响应错误码 + private void LogSendDebug(INetworkMessage msg, long actorId, int responseErrorCode) + { + if (!Setting.IsDebug || !Setting.IsDebugSend) + { + return; + } + + if (msg is IHeartBeatMessage) + { + if (Setting.IsDebugSendHeartBeat) + { + LogHelper.Debug("Send HeartBeat Message:{actorId} {message}", actorId, LocalizationService.GetString(Keys.NetWork.MessageSent, msg.ToFormatMessageString(actorId))); + } + } + else + { + LogHelper.Debug("Send Message:{actorId} {errorCode} {message}", actorId, responseErrorCode, LocalizationService.GetString(Keys.NetWork.MessageSent, msg.ToFormatMessageString(actorId))); + } + } + /// /// Close the channel / 关闭通道 /// @@ -187,6 +202,18 @@ public void Close() _cancellationTokenSource.Cancel(); KcpSession.Close(); ClearData(); + _cancellationTokenSource.Dispose(); + } + + /// + /// Releases resources held by this channel / 释放本通道持有的资源 + /// + /// + /// Disposes the cancellation token source. Delegates to so the shutdown and disposal paths share one cleanup sequence. + /// + public void Dispose() + { + Close(); } ///