From 8a66edd3e0a725709f98e16422768ccab994981a Mon Sep 17 00:00:00 2001 From: bang <3656828039@qq.com> Date: Thu, 21 May 2026 19:56:17 +0800 Subject: [PATCH] =?UTF-8?q?fix(net):=20Stop()=20=E5=B9=82=E7=AD=89?= =?UTF-8?q?=E5=8C=96,=20=E4=B8=8D=20close=20msgChan/msgBuffChan,=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E8=AF=B7=E6=B1=82=E5=90=8E=20server=20?= =?UTF-8?q?=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - stopOnce 替代 isClose 标志, 自然防止 double-Stop - 删除裸 recover() 与 close(msgChan)/close(msgBuffChan): worker 仍可能在 SendBuffMsg, close 触发 send on closed channel - ExitBuffChan 改非阻塞 send, 防止 Stop 在 buffer 已满时永阻塞 Co-Authored-By: Claude Opus 4.7 (1M context) --- network/banNet/connection.go | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/network/banNet/connection.go b/network/banNet/connection.go index 2c7fd85..53fa266 100644 --- a/network/banNet/connection.go +++ b/network/banNet/connection.go @@ -19,8 +19,8 @@ type Connection struct { Conn *net.TCPConn // 链接的唯一 ID ConnID uint32 - // 该链接是否关闭 - isClose bool + // Stop 幂等化 + stopOnce sync.Once MsgHandle banIface.IMsgHandle // 该链接状态 ExitBuffChan chan bool @@ -44,10 +44,9 @@ func NewConnection(conn *net.TCPConn, ConnID uint32, handle banIface.IMsgHandle, ConnID: ConnID, MsgHandle: handle, ExitBuffChan: make(chan bool, 1), - isClose: false, ctx: ctx, cancel: cancel, - msgChan: make(chan []byte, 10), // 高优通道加小缓冲,避免硬阻塞 + msgChan: make(chan []byte, 10), // 高优通道加小缓冲,避免硬阻塞 msgBuffChan: make(chan []byte, config.G.MaxMsgChanLen), } c.TCPServer.GetConnMgr().Add(c) @@ -149,22 +148,19 @@ func (c *Connection) Start() { } func (c *Connection) Stop() { - fmt.Println("[Connection] terminated — ID:", c.ConnID) - if c.isClose == true { - return - } - c.isClose = true - c.TCPServer.CallConnStopFunc(c) - c.cancel() - c.Conn.Close() - c.ExitBuffChan <- true - c.TCPServer.GetConnMgr().Remove(c) - defer func() { - recover() - }() - close(c.ExitBuffChan) - close(c.msgChan) - close(c.msgBuffChan) + c.stopOnce.Do(func() { + fmt.Println("[Connection] terminated — ID:", c.ConnID) + c.TCPServer.CallConnStopFunc(c) + c.cancel() + c.Conn.Close() + // 非阻塞通知 Start/Writer 退出;多次入口被 stopOnce 折叠 + select { + case c.ExitBuffChan <- true: + default: + } + c.TCPServer.GetConnMgr().Remove(c) + // 不 close msgChan / msgBuffChan:worker 可能仍在 SendBuffMsg,close 会触发 send on closed channel + }) } func (c *Connection) GetConnID() uint32 { return c.ConnID