Browse Source

Switch to V5 gateway (#300)

This switch the gateway to V5, and change the heartbeat logic to
get the heartbeat_interval from the new Hello opcode instant of
READY/RESUME event.
See: https://github.com/hammerandchisel/discord-api-docs/issues/18

Fix: #220
Kristian Klausen 8 years ago
parent
commit
b377944b97
4 changed files with 26 additions and 27 deletions
  1. 0 12
      event.go
  2. 7 10
      events.go
  3. 3 4
      state.go
  4. 16 1
      wsapi.go

+ 0 - 12
event.go

@@ -211,8 +211,6 @@ func (s *Session) onInterface(i interface{}) {
 		setGuildIds(t.Guild)
 	case *GuildUpdate:
 		setGuildIds(t.Guild)
-	case *Resumed:
-		s.onResumed(t)
 	case *VoiceServerUpdate:
 		go s.onVoiceServerUpdate(t)
 	case *VoiceStateUpdate:
@@ -229,14 +227,4 @@ func (s *Session) onReady(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)
-}
-
-// onResumed handles the resumed event.
-func (s *Session) onResumed(r *Resumed) {
-
-	// Start the heartbeat to keep the connection alive.
-	go s.heartbeat(s.wsConn, s.listening, r.HeartbeatInterval)
 }

+ 7 - 10
events.go

@@ -2,7 +2,6 @@ package discordgo
 
 import (
 	"encoding/json"
-	"time"
 )
 
 // This file contains all the possible structs that can be
@@ -37,13 +36,12 @@ type Event struct {
 
 // A Ready stores all data for the websocket READY event.
 type Ready struct {
-	Version           int           `json:"v"`
-	SessionID         string        `json:"session_id"`
-	HeartbeatInterval time.Duration `json:"heartbeat_interval"`
-	User              *User         `json:"user"`
-	ReadState         []*ReadState  `json:"read_state"`
-	PrivateChannels   []*Channel    `json:"private_channels"`
-	Guilds            []*Guild      `json:"guilds"`
+	Version         int          `json:"v"`
+	SessionID       string       `json:"session_id"`
+	User            *User        `json:"user"`
+	ReadState       []*ReadState `json:"read_state"`
+	PrivateChannels []*Channel   `json:"private_channels"`
+	Guilds          []*Guild     `json:"guilds"`
 
 	// Undocumented fields
 	Settings          *Settings            `json:"user_settings"`
@@ -191,8 +189,7 @@ type PresenceUpdate struct {
 
 // Resumed is the data for a Resumed event.
 type Resumed struct {
-	HeartbeatInterval time.Duration `json:"heartbeat_interval"`
-	Trace             []string      `json:"_trace"`
+	Trace []string `json:"_trace"`
 }
 
 // RelationshipAdd is the data for a RelationshipAdd event.

+ 3 - 4
state.go

@@ -609,10 +609,9 @@ func (s *State) onReady(se *Session, r *Ready) (err error) {
 	// if state is disabled, store the bare essentials.
 	if !se.StateEnabled {
 		ready := Ready{
-			Version:           r.Version,
-			SessionID:         r.SessionID,
-			HeartbeatInterval: r.HeartbeatInterval,
-			User:              r.User,
+			Version:   r.Version,
+			SessionID: r.SessionID,
+			User:      r.User,
 		}
 
 		s.Ready = ready

+ 16 - 1
wsapi.go

@@ -74,7 +74,7 @@ func (s *Session) Open() (err error) {
 		}
 
 		// Add the version and encoding to the URL
-		s.gateway = fmt.Sprintf("%s?v=4&encoding=json", s.gateway)
+		s.gateway = fmt.Sprintf("%s?v=5&encoding=json", s.gateway)
 	}
 
 	header := http.Header{}
@@ -180,6 +180,11 @@ type heartbeatOp struct {
 	Data int `json:"d"`
 }
 
+type helloOp struct {
+	HeartbeatInterval time.Duration `json:"heartbeat_interval"`
+	Trace             []string      `json:"_trace"`
+}
+
 // heartbeat sends regular heartbeats to Discord so it knows the client
 // is still connected.  If you do not send these heartbeats Discord will
 // disconnect the websocket connection after a few seconds.
@@ -396,6 +401,16 @@ func (s *Session) onEvent(messageType int, message []byte) {
 		return
 	}
 
+	if e.Operation == 10 {
+		var h helloOp
+		if err = json.Unmarshal(e.RawData, &h); err != nil {
+			s.log(LogError, "error unmarshalling helloOp, %s", err)
+		} else {
+			go s.heartbeat(s.wsConn, s.listening, h.HeartbeatInterval)
+		}
+		return
+	}
+
 	// Do not try to Dispatch a non-Dispatch Message
 	if e.Operation != 0 {
 		// But we probably should be doing something with them.