@@ -21,6 +21,7 @@ const (
21
21
baseProtocolMaxMsgSize = 10 * 1024 * 1024
22
22
23
23
disconnectGracePeriod = 2 * time .Second
24
+ pingInterval = 15 * time .Second
24
25
)
25
26
26
27
const (
@@ -118,19 +119,33 @@ func (p *Peer) run() DiscReason {
118
119
p .startProtocols ()
119
120
go func () { readErr <- p .readLoop () }()
120
121
122
+ ping := time .NewTicker (pingInterval )
123
+ defer ping .Stop ()
124
+
121
125
// Wait for an error or disconnect.
122
126
var reason DiscReason
123
- select {
124
- case err := <- readErr :
125
- // We rely on protocols to abort if there is a write error. It
126
- // might be more robust to handle them here as well.
127
- p .DebugDetailf ("Read error: %v\n " , err )
128
- p .rw .Close ()
129
- return DiscNetworkError
130
-
131
- case err := <- p .protoErr :
132
- reason = discReasonForError (err )
133
- case reason = <- p .disc :
127
+ loop:
128
+ for {
129
+ select {
130
+ case <- ping .C :
131
+ go func () {
132
+ if err := EncodeMsg (p .rw , pingMsg , nil ); err != nil {
133
+ p .protoErr <- err
134
+ return
135
+ }
136
+ }()
137
+ case err := <- readErr :
138
+ // We rely on protocols to abort if there is a write error. It
139
+ // might be more robust to handle them here as well.
140
+ p .DebugDetailf ("Read error: %v\n " , err )
141
+ p .rw .Close ()
142
+ return DiscNetworkError
143
+ case err := <- p .protoErr :
144
+ reason = discReasonForError (err )
145
+ break loop
146
+ case reason = <- p .disc :
147
+ break loop
148
+ }
134
149
}
135
150
p .politeDisconnect (reason )
136
151
0 commit comments