From 6c0b89965cdf79a1df5c14fa4e0697d133563367 Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Mon, 25 Apr 2016 21:33:22 -0500 Subject: [PATCH] slightly better handling of voice disconnects We now check if the voice connection disconencted due to a call to Voice.Close() and if so it does not emit an error message. --- voice.go | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/voice.go b/voice.go index eec18f6..b1bbd6d 100644 --- a/voice.go +++ b/voice.go @@ -30,7 +30,7 @@ import ( // A VoiceConnection struct holds all the data and functions related to a Discord Voice Connection. type VoiceConnection struct { - sync.Mutex + sync.RWMutex Debug bool // If true, print extra logging Ready bool // If true, voice is ready to send/receive audio @@ -280,10 +280,25 @@ func (v *VoiceConnection) wsListen(wsConn *websocket.Conn, close <-chan struct{} for { messageType, message, err := v.wsConn.ReadMessage() if err != nil { - // TODO: add reconnect, matching wsapi.go:listen() - // TODO: Handle this problem better. - // TODO: needs proper logging - log.Println("VoiceConnection Listen Error:", err) + // 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. + v.RLock() + sameConnection := v.wsConn == wsConn + v.RUnlock() + if sameConnection { + + log.Println("voice websocket closed unexpectantly,", err) + + // There has been an error reading, Close() the websocket so that + // OnDisconnect is fired. + // TODO add Voice OnDisconnect event :) + v.Close() + // TODO: close should return errs like data websocket Close + + // Attempt to reconnect, with expenonential backoff up to 10 minutes. + // TODO add reconnect code + } return } @@ -678,7 +693,25 @@ func (v *VoiceConnection) opusReceiver(udpConn *net.UDPConn, close <-chan struct for { rlen, err := udpConn.Read(recvbuf) if err != nil { - log.Println("opusReceiver UDP Read error:", err) + // Detect if we have been closed manually. If a Close() has already + // happened, the udp connection we are listening on will be different + // to the current session. + v.RLock() + sameConnection := v.udpConn == udpConn + v.RUnlock() + if sameConnection { + + log.Println("voice udp connection closed unexpectantly,", err) + + // There has been an error reading, Close() the websocket so that + // OnDisconnect is fired. + // TODO add Voice OnDisconnect event :) + v.Close() + // TODO: close should return errs like data websocket Close + + // Attempt to reconnect, with expenonential backoff up to 10 minutes. + // TODO add reconnect code + } return }