9 | 9 |
"time"
|
10 | 10 |
|
11 | 11 |
"github.com/gorilla/websocket"
|
|
12 |
"github.com/nlopes/slack/internal/errorsx"
|
12 | 13 |
"github.com/nlopes/slack/internal/timex"
|
13 | 14 |
)
|
14 | 15 |
|
|
137 | 138 |
ErrorObj: err,
|
138 | 139 |
}}
|
139 | 140 |
|
140 | |
// check if Disconnect() has been invoked.
|
|
141 |
// get time we should wait before attempting to connect again
|
|
142 |
rtm.Debugf("reconnection %d failed: %s reconnecting in %v\n", boff.attempts, err, backoff)
|
|
143 |
|
|
144 |
// wait for one of the following to occur,
|
|
145 |
// backoff duration has elapsed, killChannel is signalled, or
|
|
146 |
// the rtm finishes disconnecting.
|
141 | 147 |
select {
|
|
148 |
case <-time.After(backoff): // retry after the backoff.
|
142 | 149 |
case intentional := <-rtm.killChannel:
|
143 | 150 |
if intentional {
|
144 | |
rtm.killConnection(intentional)
|
|
151 |
rtm.killConnection(intentional, ErrRTMDisconnected)
|
145 | 152 |
return nil, nil, ErrRTMDisconnected
|
146 | 153 |
}
|
147 | 154 |
case <-rtm.disconnected:
|
148 | 155 |
return nil, nil, ErrRTMDisconnected
|
149 | |
default:
|
150 | |
}
|
151 | |
|
152 | |
// get time we should wait before attempting to connect again
|
153 | |
rtm.Debugf("reconnection %d failed: %s reconnecting in %v\n", boff.attempts, err, backoff)
|
154 | |
time.Sleep(backoff)
|
|
156 |
}
|
155 | 157 |
}
|
156 | 158 |
}
|
157 | 159 |
|
|
204 | 206 |
//
|
205 | 207 |
// This should not be called directly! Instead a boolean value (true for
|
206 | 208 |
// intentional, false otherwise) should be sent to the killChannel on the RTM.
|
207 | |
func (rtm *RTM) killConnection(intentional bool) (err error) {
|
|
209 |
func (rtm *RTM) killConnection(intentional bool, cause error) (err error) {
|
208 | 210 |
rtm.Debugln("killing connection")
|
209 | 211 |
|
210 | 212 |
if rtm.conn != nil {
|
211 | 213 |
err = rtm.conn.Close()
|
212 | 214 |
}
|
213 | 215 |
|
214 | |
rtm.IncomingEvents <- RTMEvent{"disconnected", &DisconnectedEvent{intentional}}
|
|
216 |
rtm.IncomingEvents <- RTMEvent{"disconnected", &DisconnectedEvent{Intentional: intentional, Cause: cause}}
|
215 | 217 |
|
216 | 218 |
if intentional {
|
217 | 219 |
rtm.disconnect()
|
|
232 | 234 |
select {
|
233 | 235 |
// catch "stop" signal on channel close
|
234 | 236 |
case intentional := <-rtm.killChannel:
|
235 | |
_ = rtm.killConnection(intentional)
|
|
237 |
_ = rtm.killConnection(intentional, errorsx.String("signaled"))
|
236 | 238 |
return
|
237 | 239 |
// detect when the connection is dead.
|
238 | 240 |
case <-rtm.pingDeadman.C:
|
239 | |
rtm.Debugln("deadman switch trigger disconnecting")
|
240 | |
_ = rtm.killConnection(false)
|
|
241 |
_ = rtm.killConnection(false, errorsx.String("deadman switch triggered"))
|
241 | 242 |
return
|
242 | 243 |
// send pings on ticker interval
|
243 | 244 |
case <-ticker.C:
|
244 | 245 |
if err := rtm.ping(); err != nil {
|
245 | |
_ = rtm.killConnection(false)
|
|
246 |
_ = rtm.killConnection(false, err)
|
246 | 247 |
return
|
247 | 248 |
}
|
248 | 249 |
case <-rtm.forcePing:
|
249 | 250 |
if err := rtm.ping(); err != nil {
|
250 | |
_ = rtm.killConnection(false)
|
|
251 |
_ = rtm.killConnection(false, err)
|
251 | 252 |
return
|
252 | 253 |
}
|
253 | 254 |
// listen for messages that need to be sent
|
|
257 | 258 |
case rawEvent := <-rtm.rawEvents:
|
258 | 259 |
switch rtm.handleRawEvent(rawEvent) {
|
259 | 260 |
case rtmEventTypeGoodbye:
|
260 | |
_ = rtm.killConnection(false)
|
|
261 |
_ = rtm.killConnection(false, errorsx.String("goodbye detected"))
|
261 | 262 |
return
|
262 | 263 |
default:
|
263 | 264 |
}
|
|
309 | 310 |
Message: msg,
|
310 | 311 |
ErrorObj: err,
|
311 | 312 |
}}
|
312 | |
// TODO force ping?
|
313 | 313 |
}
|
314 | 314 |
}
|
315 | 315 |
|