Add connect timeout, fix ChannelVoiceJoin "leaking" connections
This commit is contained in:
parent
b48e8c992e
commit
5dc0b9f2a1
3 changed files with 40 additions and 16 deletions
|
@ -54,7 +54,7 @@ type Session struct {
|
|||
// Whether the UDP Connection is ready
|
||||
UDPReady bool
|
||||
|
||||
// Stores a mapping of channel id's to VoiceConnections
|
||||
// Stores a mapping of guild id's to VoiceConnections
|
||||
VoiceConnections map[string]*VoiceConnection
|
||||
|
||||
// Managed state object, updated internally with events when
|
||||
|
|
28
voice.go
28
voice.go
|
@ -12,6 +12,7 @@ package discordgo
|
|||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
|
@ -97,7 +98,6 @@ type voiceHandshakeOp struct {
|
|||
// after VoiceConnectionChannelJoin is used and the data VOICE websocket events
|
||||
// are captured.
|
||||
func (v *VoiceConnection) Open() (err error) {
|
||||
|
||||
v.Lock()
|
||||
defer v.Unlock()
|
||||
|
||||
|
@ -131,8 +131,19 @@ func (v *VoiceConnection) Open() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (v *VoiceConnection) WaitUntilConnected() {
|
||||
<-v.connected
|
||||
func (v *VoiceConnection) WaitUntilConnected() error {
|
||||
if v.Ready {
|
||||
return nil
|
||||
}
|
||||
|
||||
value, ok := <-v.connected
|
||||
|
||||
if (!value && !v.Ready) || !ok {
|
||||
delete(v.session.VoiceConnections, v.GuildID)
|
||||
return errors.New("Timed out connecting to voice")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// wsListen listens on the voice websocket for messages and passes them
|
||||
|
@ -603,9 +614,11 @@ func (v *VoiceConnection) Close() {
|
|||
v.Lock()
|
||||
defer v.Unlock()
|
||||
|
||||
if v.Ready {
|
||||
// Send a OP4 with a nil channel to disconnect
|
||||
if v.sessionID != "" {
|
||||
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, nil, true, true}}
|
||||
v.session.wsConn.WriteJSON(data)
|
||||
v.sessionID = ""
|
||||
}
|
||||
|
||||
v.Ready = false
|
||||
|
@ -632,15 +645,10 @@ func (v *VoiceConnection) Close() {
|
|||
}
|
||||
}
|
||||
|
||||
// Change channels
|
||||
// Request to change channels
|
||||
func (v *VoiceConnection) ChangeChannel(channelID string) (err error) {
|
||||
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, &channelID, true, true}}
|
||||
|
||||
err = v.session.wsConn.WriteJSON(data)
|
||||
|
||||
if err == nil {
|
||||
v.ChannelID = channelID
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
18
wsapi.go
18
wsapi.go
|
@ -336,7 +336,13 @@ type voiceChannelJoinOp struct {
|
|||
// cID : Channel ID of the channel to join.
|
||||
// mute : If true, you will be set to muted upon joining.
|
||||
// deaf : If true, you will be set to deafened upon joining.
|
||||
func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool) (voice *VoiceConnection, err error) {
|
||||
// timeout : If greater than zero, the timeout in milliseconds after which connecting will fail
|
||||
func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool, timeout int) (voice *VoiceConnection, err error) {
|
||||
// If a voice connection for the guild exists, return that
|
||||
if _, exists := s.VoiceConnections[gID]; exists {
|
||||
return s.VoiceConnections[gID], err
|
||||
}
|
||||
|
||||
// Send the request to Discord that we want to join the voice channel
|
||||
data := voiceChannelJoinOp{4, voiceChannelJoinData{&gID, &cID, mute, deaf}}
|
||||
err = s.wsConn.WriteJSON(data)
|
||||
|
@ -359,6 +365,16 @@ func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool) (voice *Voi
|
|||
voice.GuildID = gID
|
||||
voice.ChannelID = cID
|
||||
|
||||
// Queue the timeout in case we fail to connect
|
||||
if timeout > 0 {
|
||||
go func() {
|
||||
time.Sleep(time.Millisecond * time.Duration(timeout))
|
||||
if !voice.Ready {
|
||||
voice.connected <- false
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return voice, err
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue