@@ -43,18 +43,16 @@ var busClosing atomic.Bool
4343var busClosingMu sync.Mutex
4444var busClosingWG sync.WaitGroup
4545
46- var globalActiveChecker * timeoutChecker
46+ var clientAliveTime aliveTime
47+ var pendingClearPktCache bool
4748
4849func sendBusMessage (command string , msg any ) error {
4950 busMutex .Lock ()
5051 defer busMutex .Unlock ()
5152 if busStream == nil {
5253 return fmt .Errorf ("bus stream is nil" )
5354 }
54- if err := sendCommand (busStream , command ); err != nil {
55- return err
56- }
57- return sendMessage (busStream , msg )
55+ return sendCommandAndMessage (busStream , command , msg )
5856}
5957
6058func initBusStream (stream Stream ) error {
@@ -101,27 +99,13 @@ func handleBusEvent(stream Stream) {
10199
102100 serving .Store (true )
103101
104- globalActiveChecker = newTimeoutChecker (msg .HeartbeatTimeout )
105- if enableDebugLogging {
106- globalActiveChecker .onTimeout (func () {
107- debug ("transport offline, last activity at %v" , time .UnixMilli (globalActiveChecker .getAliveTime ()).Format ("15:04:05.000" ))
108- })
109- globalActiveChecker .onReconnected (func () {
110- debug ("transport resumed, last activity at %v" , time .UnixMilli (globalActiveChecker .getAliveTime ()).Format ("15:04:05.000" ))
111- })
112- }
113- globalActiveChecker .onReconnected (func () {
114- totalSize , totalCount := globalServerProxy .pktCache .clearCache ()
115- if enableDebugLogging {
116- debug ("drop packet cache count [%d] cache size [%d]" , totalCount , totalSize )
117- }
118- })
102+ intervalTime := int64 (msg .IntervalTime / time .Millisecond )
103+ heartbeatTimeout := int64 (msg .HeartbeatTimeout / time .Millisecond )
119104
120- globalServerProxy .clientChecker .timeoutMilli .Store (int64 ( msg . HeartbeatTimeout / time . Millisecond ) )
105+ globalServerProxy .clientChecker .timeoutMilli .Store (heartbeatTimeout )
121106
122- activeAckChan := make (chan int64 , 1 )
123- defer close (activeAckChan )
124- go keepAlive (msg .AliveTimeout , msg .IntervalTime , activeAckChan )
107+ clientAliveTime .addMilli (time .Now ().UnixMilli ())
108+ go keepAlive (msg .AliveTimeout , msg .IntervalTime )
125109
126110 for {
127111 command , err := recvCommand (stream )
@@ -141,10 +125,8 @@ func handleBusEvent(stream Stream) {
141125 case "close" :
142126 handleCloseEvent ()
143127 return // return will close the bus stream
144- case "alive1" :
145- err = handleAlive1Event (stream , activeAckChan )
146- case "alive2" :
147- err = handleAlive2Event (stream )
128+ case "alive" :
129+ err = handleAliveEvent (stream , heartbeatTimeout , intervalTime )
148130 case "setting" :
149131 err = handleSettingEvent (stream )
150132 default :
@@ -189,23 +171,39 @@ func handleCloseEvent() {
189171 }()
190172}
191173
192- func handleAlive1Event (stream Stream , activeAckChan chan <- int64 ) error {
174+ func handleAliveEvent (stream Stream , heartbeatTimeout , intervalTime int64 ) error {
193175 var msg aliveMessage
194176 if err := recvMessage (stream , & msg ); err != nil {
195177 return fmt .Errorf ("recv alive message failed: %v" , err )
196178 }
197179
198- activeAckChan <- msg .Time
199- return nil
200- }
180+ now := time .Now ().UnixMilli ()
201181
202- func handleAlive2Event (stream Stream ) error {
203- var msg aliveMessage
204- if err := recvMessage (stream , & msg ); err != nil {
205- return fmt .Errorf ("recv alive message failed: %v" , err )
182+ // If the time since the last recorded activity exceeds heartbeatTimeout,
183+ // it indicates that the client was previously disconnected and has now reconnected.
184+ // Set the flag to clear the packet cache after the client stabilizes.
185+ if now - clientAliveTime .latest () > heartbeatTimeout {
186+ debug ("client reconnected, last active at %v" , time .UnixMilli (clientAliveTime .latest ()).Format ("15:04:05.000" ))
187+ pendingClearPktCache = true
188+ } else if enableDebugLogging && pendingClearPktCache {
189+ debug ("client active at %v" , time .UnixMilli (now ).Format ("15:04:05.000" ))
190+ }
191+
192+ clientAliveTime .addMilli (now )
193+
194+ if pendingClearPktCache {
195+ // If the client has remained active for a sufficient number of intervals,
196+ // consider the connection stable and clear the packet cache.
197+ if now - clientAliveTime .oldest () < (kAliveTimeCap + 1 )* intervalTime {
198+ totalSize , totalCount := globalServerProxy .pktCache .clearCache ()
199+ if enableDebugLogging && (totalSize > 0 || totalCount > 0 ) {
200+ debug ("drop packet cache count [%d] size [%d]" , totalCount , totalSize )
201+ }
202+ pendingClearPktCache = false
203+ }
206204 }
207205
208- return sendBusMessage ("alive2 " , msg )
206+ return sendBusMessage ("alive " , msg )
209207}
210208
211209func handleSettingEvent (stream Stream ) error {
@@ -230,29 +228,10 @@ func handleUnknownEvent(stream Stream, command string) error {
230228 return fmt .Errorf ("unknown command: %s" , command )
231229}
232230
233- func keepAlive (totalTimeout time.Duration , intervalTime time.Duration , activeAckChan <- chan int64 ) {
234- ticker := time .NewTicker (intervalTime )
235- defer ticker .Stop ()
236- go func () {
237- for range ticker .C {
238- aliveTime := time .Now ().UnixMilli ()
239- if enableDebugLogging && globalActiveChecker .isTimeout () {
240- debug ("sending new keep alive [%d]" , aliveTime )
241- }
242- if err := sendBusMessage ("alive1" , aliveMessage {aliveTime }); err != nil {
243- warning ("send keep alive [%d] failed: %v" , aliveTime , err )
244- } else if enableDebugLogging && globalActiveChecker .isTimeout () {
245- debug ("keep alive [%d] sent success" , aliveTime )
246- }
247-
248- ackTime := <- activeAckChan
249- globalActiveChecker .updateTime (ackTime )
250- }
251- }()
252-
253- timeoutMilli := int64 (totalTimeout / time .Millisecond )
231+ func keepAlive (aliveTimeout time.Duration , intervalTime time.Duration ) {
232+ timeoutMilli := int64 (aliveTimeout / time .Millisecond )
254233 for {
255- if time .Now ().UnixMilli ()- globalActiveChecker . getAliveTime () > timeoutMilli {
234+ if time .Now ().UnixMilli ()- clientAliveTime . latest () > timeoutMilli {
256235 warning ("tsshd keep alive timeout" )
257236 exitChan <- 2
258237 return
0 commit comments