@@ -22,6 +22,7 @@ import (
22
22
"crypto/x509"
23
23
"encoding/pem"
24
24
"fmt"
25
+ "math"
25
26
"net"
26
27
"os"
27
28
"strings"
@@ -41,10 +42,11 @@ import (
41
42
)
42
43
43
44
const (
44
- reconnectInterval = 3e8 // 300ms
45
- connectInterval = 5e8 // 500ms
46
- connectTimeout = 3e9
47
- maxTimes = 10
45
+ defaultReconnectInterval = 3e8 // 300ms
46
+ connectInterval = 5e8 // 500ms
47
+ connectTimeout = 3e9
48
+ defaultMaxReconnectAttempts = 50
49
+ maxBackOffTimes = 10
48
50
)
49
51
50
52
var (
@@ -207,14 +209,18 @@ func (c *client) dialUDP() Session {
207
209
}
208
210
209
211
// check connection alive by write/read action
210
- conn .SetWriteDeadline (time .Now ().Add (1e9 ))
212
+ if err := conn .SetWriteDeadline (time .Now ().Add (1e9 )); err != nil {
213
+ log .Warnf ("failed to set write deadline: %+v" , err )
214
+ }
211
215
if length , err = conn .Write (connectPingPackage [:]); err != nil {
212
216
conn .Close ()
213
217
log .Warnf ("conn.Write(%s) = {length:%d, err:%+v}" , string (connectPingPackage ), length , perrors .WithStack (err ))
214
218
<- gxtime .After (connectInterval )
215
219
continue
216
220
}
217
- conn .SetReadDeadline (time .Now ().Add (1e9 ))
221
+ if err := conn .SetReadDeadline (time .Now ().Add (1e9 )); err != nil {
222
+ log .Warnf ("failed to set read deadline: %+v" , err )
223
+ }
218
224
length , err = conn .Read (buf )
219
225
if netErr , ok := perrors .Cause (err ).(net.Error ); ok && netErr .Timeout () {
220
226
err = nil
@@ -423,33 +429,33 @@ func (c *client) RunEventLoop(newSession NewSessionCallback) {
423
429
// a for-loop connect to make sure the connection pool is valid
424
430
func (c * client ) reConnect () {
425
431
var (
426
- num , max , times , interval int
427
- maxDuration int64
432
+ sessionNum , reconnectAttempts int
433
+ maxReconnectInterval int64
428
434
)
429
- max = c .number
430
- interval = c .reconnectInterval
431
- if interval == 0 {
432
- interval = reconnectInterval
435
+ reconnectInterval := c .reconnectInterval
436
+ if reconnectInterval == 0 {
437
+ reconnectInterval = defaultReconnectInterval
438
+ }
439
+ maxReconnectAttempts := c .maxReconnectAttempts
440
+ if maxReconnectAttempts == 0 {
441
+ maxReconnectAttempts = defaultMaxReconnectAttempts
433
442
}
443
+ connPoolSize := c .number
434
444
for {
435
445
if c .IsClosed () {
436
446
log .Warnf ("client{peer:%s} goroutine exit now." , c .addr )
437
447
break
438
448
}
439
449
440
- num = c .sessionNum ()
441
- if max <= num || max < times {
442
- //Exit when the number of connection pools is sufficient or the reconnection times exceeds the connections numbers .
450
+ sessionNum = c .sessionNum ()
451
+ if connPoolSize <= sessionNum || maxReconnectAttempts < reconnectAttempts {
452
+ //exit reconnect when the number of connection pools is sufficient or the current reconnection attempts exceeds the max reconnection attempts .
443
453
break
444
454
}
445
455
c .connect ()
446
- times ++
447
- if times > maxTimes {
448
- maxDuration = int64 (maxTimes ) * int64 (interval )
449
- } else {
450
- maxDuration = int64 (times ) * int64 (interval )
451
- }
452
- <- gxtime .After (time .Duration (maxDuration ))
456
+ reconnectAttempts ++
457
+ maxReconnectInterval = int64 (math .Min (float64 (reconnectAttempts ), float64 (maxBackOffTimes ))) * int64 (reconnectInterval )
458
+ <- gxtime .After (time .Duration (maxReconnectInterval ))
453
459
}
454
460
}
455
461
0 commit comments