@@ -51,11 +51,9 @@ func (c *Conn) readControl() error {
5151 var opcode = c .fh .GetOpcode ()
5252 switch opcode {
5353 case OpcodePing :
54- c .handler .OnPing (c , payload )
55- return nil
54+ return c .dispatchControl (OpcodePing , payload , nil )
5655 case OpcodePong :
57- c .handler .OnPong (c , payload )
58- return nil
56+ return c .dispatchControl (OpcodePong , payload , nil )
5957 case OpcodeCloseConnection :
6058 return c .emitClose (bytes .NewBuffer (payload ))
6159 default :
@@ -151,12 +149,30 @@ func (c *Conn) readMessage() error {
151149
152150// 分发消息和异常恢复
153151// Dispatch message & Recovery
154- func (c * Conn ) dispatch (msg * Message ) error {
152+ func (c * Conn ) dispatchMessage (msg * Message ) error {
155153 defer c .config .Recovery (c .config .Logger )
156154 c .handler .OnMessage (c , msg )
157155 return nil
158156}
159157
158+ // 分发控制帧事件并进行异常恢复
159+ // Dispatch control-frame events with recovery
160+ //
161+ // 控制帧(Ping/Pong/Close)的回调如果发生 panic,不应直接导致 ReadLoop 崩溃;
162+ // 因此这里统一通过 Config.Recovery 进行兜底。
163+ func (c * Conn ) dispatchControl (opcode Opcode , payload []byte , err error ) error {
164+ defer c .config .Recovery (c .config .Logger )
165+ switch opcode {
166+ case OpcodePing :
167+ c .handler .OnPing (c , payload )
168+ case OpcodePong :
169+ c .handler .OnPong (c , payload )
170+ case OpcodeCloseConnection :
171+ c .handler .OnClose (c , err )
172+ }
173+ return nil
174+ }
175+
160176// 发射消息事件
161177// Emit onmessage event
162178func (c * Conn ) emitMessage (msg * Message ) (err error ) {
@@ -171,7 +187,7 @@ func (c *Conn) emitMessage(msg *Message) (err error) {
171187 return internal .NewError (internal .CloseUnsupportedData , ErrTextEncoding )
172188 }
173189 if c .config .ParallelEnabled {
174- return c .readQueue .Go (msg , c .dispatch )
190+ return c .readQueue .Go (msg , c .dispatchMessage )
175191 }
176- return c .dispatch (msg )
192+ return c .dispatchMessage (msg )
177193}
0 commit comments