From f6de2b2c98b7751131b9e44c080d6691ebecdc0e Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Thu, 28 Apr 2016 21:15:32 -0500 Subject: [PATCH] gateway, voice, & logging improvements We now store teh sessionID of the gateway connection for later use. We are now caching the gateway url and will use it until unable to connect to that gateway. We're not longer smashing the VoiceConnections map during reconnects which was causing Voice problems. Slight change to log output format. --- discord.go | 4 ++++ logging.go | 2 +- structs.go | 6 ++++++ wsapi.go | 50 ++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/discord.go b/discord.go index 99a343f..72c848f 100644 --- a/discord.go +++ b/discord.go @@ -237,5 +237,9 @@ func (s *Session) initialize() { // onReady handles the ready event. func (s *Session) onReady(se *Session, r *Ready) { + // Store the SessionID within the Session struct. + s.sessionID = r.SessionID + + // Start the heartbeat to keep the connection alive. go s.heartbeat(s.wsConn, s.listening, r.HeartbeatInterval) } diff --git a/logging.go b/logging.go index 6c59760..7c487ed 100644 --- a/logging.go +++ b/logging.go @@ -57,7 +57,7 @@ func msglog(msgL, caller int, format string, a ...interface{}) { msg := fmt.Sprintf(format, a...) - log.Printf("[DG%d] %s:%d %s %s\n", msgL, file, line, name, msg) + log.Printf("[DG%d] %s:%d:%s() %s\n", msgL, file, line, name, msg) } // helper function that wraps msglog for the Session struct diff --git a/structs.go b/structs.go index 2721fb3..dd7a1fc 100644 --- a/structs.go +++ b/structs.go @@ -83,6 +83,12 @@ type Session struct { // sequence tracks the current gateway api websocket sequence number sequence int + + // stores sessions current Discord Gateway + gateway string + + // stores session ID of current Gateway connection + sessionID string } type rateLimitMutex struct { diff --git a/wsapi.go b/wsapi.go index 32c0360..077d092 100644 --- a/wsapi.go +++ b/wsapi.go @@ -50,6 +50,9 @@ type handshakeOp struct { // Open opens a websocket connection to Discord. func (s *Session) Open() (err error) { + + s.log(LogInformational, "called") + s.Lock() defer func() { if err != nil { @@ -57,7 +60,10 @@ func (s *Session) Open() (err error) { } }() - s.VoiceConnections = make(map[string]*VoiceConnection) + 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.") @@ -65,27 +71,41 @@ func (s *Session) Open() (err error) { } // Get the gateway to use for the Websocket connection - g, err := s.Gateway() - if err != nil { - return - } + if s.gateway == "" { + s.gateway, err = s.Gateway() + if err != nil { + return + } - // Add the version and encoding to the URL - g = g + fmt.Sprintf("?v=%v&encoding=json", GATEWAY_VERSION) + // Add the version and encoding to the URL + s.gateway = fmt.Sprintf("%s?v=%v&encoding=json", s.gateway, GATEWAY_VERSION) + } header := http.Header{} header.Add("accept-encoding", "zlib") - // TODO: See if there's a use for the http response. - // conn, response, err := websocket.DefaultDialer.Dial(session.Gateway, nil) - s.wsConn, _, err = websocket.DefaultDialer.Dial(g, header) + s.log(LogInformational, "connecting to gateway %s", s.gateway) + s.wsConn, _, err = websocket.DefaultDialer.Dial(s.gateway, header) if err != nil { + s.log(LogWarning, "error connecting to gateway %s, %s", s.gateway, err) + s.gateway = "" // clear cached gateway + // TODO: should we add a retry block here? return } - err = s.wsConn.WriteJSON(handshakeOp{2, handshakeData{s.Token, handshakeProperties{runtime.GOOS, "Discordgo v" + VERSION, "", "", ""}, 250, s.Compress}}) - if err != nil { - return + if s.sessionID != "" && s.sequence > 0 { + + s.log(LogInformational, "sending resume packet to gateway") + // TODO: RESUME + + } else { + + 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}}) + if err != nil { + s.log(LogWarning, "error sending gateway identify packet, %s, %s", s.gateway, err) + return + } } // Create listening outside of listen, as it needs to happen inside the mutex @@ -292,12 +312,14 @@ func (s *Session) onEvent(messageType int, message []byte) { } if s.Debug { - s.log(LogDebug, "Op: %d, Seq: %d, Type: %s, Data: %s\n", e.Operation, e.Sequence, e.Type, string(e.RawData)) + s.log(LogDebug, "Op: %d, Seq: %d, Type: %s, Data: %s", e.Operation, e.Sequence, e.Type, string(e.RawData)) } // Do not try to Dispatch a non-Dispatch Message if e.Operation != 0 { // But we probably should be doing something with them. + // TEMP + s.log(LogWarning, "Op: %d, Seq: %d, Type: %s, Data: %s", e.Operation, e.Sequence, e.Type, string(e.RawData)) return }