Skip to content

Commit 98dc133

Browse files
authored
feat(Session): resume gateway url (#1307)
1 parent 6c6d3ee commit 98dc133

File tree

4 files changed

+45
-21
lines changed

4 files changed

+45
-21
lines changed

event.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,7 @@ func (s *Session) onReady(r *Ready) {
244244

245245
// Store the SessionID within the Session struct.
246246
s.sessionID = r.SessionID
247+
248+
// Store the ResumeGatewayURL within the Session struct.
249+
s.resumeGatewayURL = r.ResumeGatewayURL
247250
}

events.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@ type Event struct {
3636

3737
// A Ready stores all data for the websocket READY event.
3838
type Ready struct {
39-
Version int `json:"v"`
40-
SessionID string `json:"session_id"`
41-
User *User `json:"user"`
42-
Shard *[2]int `json:"shard"`
43-
Application *Application `json:"application"`
44-
Guilds []*Guild `json:"guilds"`
45-
PrivateChannels []*Channel `json:"private_channels"`
39+
Version int `json:"v"`
40+
SessionID string `json:"session_id"`
41+
User *User `json:"user"`
42+
Shard *[2]int `json:"shard"`
43+
ResumeGatewayURL string `json:"resume_gateway_url"`
44+
Application *Application `json:"application"`
45+
Guilds []*Guild `json:"guilds"`
46+
PrivateChannels []*Channel `json:"private_channels"`
4647
}
4748

4849
// ChannelCreate is the data for a ChannelCreate event.

structs.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ type Session struct {
126126
// sequence tracks the current gateway api websocket sequence number
127127
sequence *int64
128128

129+
// stores sessions current Discord Resume Gateway
130+
resumeGatewayURL string
131+
129132
// stores sessions current Discord Gateway
130133
gateway string
131134

wsapi.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,32 @@ func (s *Session) Open() error {
6262
return ErrWSAlreadyOpen
6363
}
6464

65+
sequence := atomic.LoadInt64(s.sequence)
66+
67+
var gateway string
6568
// Get the gateway to use for the Websocket connection
66-
if s.gateway == "" {
67-
s.gateway, err = s.Gateway()
68-
if err != nil {
69-
return err
69+
if sequence != 0 && s.sessionID != "" && s.resumeGatewayURL != "" {
70+
s.log(LogDebug, "using resume gateway %s", s.resumeGatewayURL)
71+
gateway = s.resumeGatewayURL
72+
} else {
73+
if s.gateway == "" {
74+
s.gateway, err = s.Gateway()
75+
if err != nil {
76+
return err
77+
}
7078
}
7179

72-
// Add the version and encoding to the URL
73-
s.gateway = s.gateway + "?v=" + APIVersion + "&encoding=json"
80+
gateway = s.gateway
7481
}
7582

83+
// Add the version and encoding to the URL
84+
gateway += "?v=" + APIVersion + "&encoding=json"
85+
7686
// Connect to the Gateway
77-
s.log(LogInformational, "connecting to gateway %s", s.gateway)
87+
s.log(LogInformational, "connecting to gateway %s", gateway)
7888
header := http.Header{}
7989
header.Add("accept-encoding", "zlib")
80-
s.wsConn, _, err = s.Dialer.Dial(s.gateway, header)
90+
s.wsConn, _, err = s.Dialer.Dial(gateway, header)
8191
if err != nil {
8292
s.log(LogError, "error connecting to gateway %s, %s", s.gateway, err)
8393
s.gateway = "" // clear cached gateway
@@ -123,7 +133,6 @@ func (s *Session) Open() error {
123133

124134
// Now we send either an Op 2 Identity if this is a brand new
125135
// connection or Op 6 Resume if we are resuming an existing connection.
126-
sequence := atomic.LoadInt64(s.sequence)
127136
if s.sessionID == "" && sequence == 0 {
128137

129138
// Send Op 2 Identity Packet
@@ -616,15 +625,23 @@ func (s *Session) onEvent(messageType int, message []byte) (*Event, error) {
616625
// Invalid Session
617626
// Must respond with a Identify packet.
618627
if e.Operation == 9 {
628+
s.log(LogInformational, "Closing and reconnecting in response to Op9")
629+
s.CloseWithCode(websocket.CloseServiceRestart)
619630

620-
s.log(LogInformational, "sending identify packet to gateway in response to Op9")
621-
622-
err = s.identify()
623-
if err != nil {
624-
s.log(LogWarning, "error sending gateway identify packet, %s, %s", s.gateway, err)
631+
var resumable bool
632+
if err := json.Unmarshal(e.RawData, &resumable); err != nil {
633+
s.log(LogError, "error unmarshalling invalid session event, %s", err)
625634
return e, err
626635
}
627636

637+
if !resumable {
638+
s.log(LogInformational, "Gateway session is not resumable, discarding its information")
639+
s.resumeGatewayURL = ""
640+
s.sessionID = ""
641+
atomic.StoreInt64(s.sequence, 0)
642+
}
643+
644+
s.reconnect()
628645
return e, nil
629646
}
630647

0 commit comments

Comments
 (0)