misc cleanup

This commit is contained in:
Bruce Marriner 2016-04-30 20:29:10 -05:00
parent dd0b83333c
commit 9e8cd0a735

View file

@ -69,16 +69,16 @@ func (s *Session) Open() (err error) {
}
}()
if s.VoiceConnections == nil {
s.log(LogInformational, "creating new VoiceConnections map")
s.VoiceConnections = make(map[string]*VoiceConnection)
}
if s.wsConn != nil {
err = errors.New("Web socket already opened.")
return
}
if s.VoiceConnections == nil {
s.log(LogInformational, "creating new VoiceConnections map")
s.VoiceConnections = make(map[string]*VoiceConnection)
}
// Get the gateway to use for the Websocket connection
if s.gateway == "" {
s.gateway, err = s.Gateway()
@ -121,8 +121,23 @@ func (s *Session) Open() (err error) {
} else {
data := handshakeOp{
2,
handshakeData{
s.Token,
handshakeProperties{
runtime.GOOS,
"Discordgo v" + VERSION,
"",
"",
"",
},
250,
s.Compress,
},
}
s.log(LogInformational, "sending identify packet to gateway")
err = s.wsConn.WriteJSON(handshakeOp{2, handshakeData{s.Token, handshakeProperties{runtime.GOOS, "Discordgo v" + VERSION, "", "", ""}, 250, s.Compress}})
err = s.wsConn.WriteJSON(data)
if err != nil {
s.log(LogWarning, "error sending gateway identify packet, %s, %s", s.gateway, err)
return
@ -145,6 +160,7 @@ func (s *Session) Open() (err error) {
// Close closes a websocket and stops all listening/heartbeat goroutines.
// TODO: Add support for Voice WS/UDP connections
func (s *Session) Close() (err error) {
s.Lock()
s.DataReady = false
@ -166,33 +182,45 @@ func (s *Session) Close() (err error) {
return
}
// listen polls the websocket connection for events, it will stop when
// the listening channel is closed, or an error occurs.
// listen polls the websocket connection for events, it will stop when the
// listening channel is closed, or an error occurs.
func (s *Session) listen(wsConn *websocket.Conn, listening <-chan interface{}) {
for {
messageType, message, err := wsConn.ReadMessage()
if err != nil {
// Detect if we have been closed manually. If a Close() has already
// happened, the websocket we are listening on will be different to the
// current session.
// happened, the websocket we are listening on will be different to
// the current session.
s.RLock()
sameConnection := s.wsConn == wsConn
s.RUnlock()
if sameConnection {
// There has been an error reading, Close() the websocket so that
// OnDisconnect is fired.
s.log(LogWarning, "error reading from websocket, %s", err)
// There has been an error reading, close the websocket so that
// OnDisconnect event is emitted.
err := s.Close()
if err != nil {
log.Println("error closing session connection: ", err)
s.log(LogWarning, "error closing session connection, %s", err)
}
// Attempt to reconnect, with expenonential backoff up to 10 minutes.
// Attempt to reconnect, with expenonential backoff up to
// 10 minutes.
if s.ShouldReconnectOnError {
wait := time.Duration(1)
for {
if s.Open() == nil {
return
}
<-time.After(wait * time.Second)
wait *= 2
if wait > 600 {
@ -201,17 +229,18 @@ func (s *Session) listen(wsConn *websocket.Conn, listening <-chan interface{}) {
}
}
}
return
}
select {
case <-listening:
return
default:
// TODO make s.event a variable that points to a function
// this way it will be possible for an end-user to write
// a completely custom event handler if needed.
go s.onEvent(messageType, message)
}
}
}
@ -236,8 +265,10 @@ func (s *Session) heartbeat(wsConn *websocket.Conn, listening <-chan interface{}
var err error
ticker := time.NewTicker(i * time.Millisecond)
for {
s.log(LogDebug, "sending gateway websocket heartbeat seq %d", s.sequence)
s.wsMutex.Lock()
err = wsConn.WriteJSON(heartbeatOp{1, s.sequence})
s.wsMutex.Unlock()
@ -273,16 +304,18 @@ type updateStatusOp struct {
// If idle>0 then set status to idle. If game>0 then set game.
// if otherwise, set status to active, and no game.
func (s *Session) UpdateStatus(idle int, game string) (err error) {
s.RLock()
defer s.RUnlock()
if s.wsConn == nil {
return errors.New("No websocket connection exists.")
return errors.New("no websocket connection exists")
}
var usd updateStatusData
if idle > 0 {
usd.IdleSince = &idle
}
if game != "" {
usd.Game = &updateStatusGame{game}
}