Skip to content

Commit

Permalink
Prevent concurrent writes to gateway websocket.
Browse files Browse the repository at this point in the history
  • Loading branch information
bwmarrin committed May 1, 2016
1 parent 20240f3 commit e9e9ef8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 0 deletions.
3 changes: 3 additions & 0 deletions structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ type Session struct {

// stores session ID of current Gateway connection
sessionID string

// used to make sure gateway websocket writes do not happen concurrently
wsMutex sync.Mutex
}

type rateLimitMutex struct {
Expand Down
11 changes: 11 additions & 0 deletions wsapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,10 @@ func (s *Session) heartbeat(wsConn *websocket.Conn, listening <-chan interface{}
var err error
ticker := time.NewTicker(i * time.Millisecond)
for {

s.wsMutex.Lock()
err = wsConn.WriteJSON(heartbeatOp{1, s.sequence})
s.wsMutex.Unlock()
if err != nil {
log.Println("Error sending heartbeat:", err)
return
Expand Down Expand Up @@ -284,7 +287,9 @@ func (s *Session) UpdateStatus(idle int, game string) (err error) {
usd.Game = &updateStatusGame{game}
}

s.wsMutex.Lock()
err = s.wsConn.WriteJSON(updateStatusOp{3, usd})
s.wsMutex.Unlock()

return
}
Expand Down Expand Up @@ -340,7 +345,9 @@ func (s *Session) onEvent(messageType int, message []byte) {
// Must respond with a heartbeat packet within 5 seconds
if e.Operation == 1 {
s.log(LogInformational, "sending heartbeat in response to Op1")
s.wsMutex.Lock()
err = s.wsConn.WriteJSON(heartbeatOp{1, s.sequence})
s.wsMutex.Unlock()
if err != nil {
s.log(LogError, "error sending heartbeat in response to Op1")
return
Expand All @@ -358,7 +365,9 @@ func (s *Session) onEvent(messageType int, message []byte) {
if e.Operation == 9 {

s.log(LogInformational, "sending identify packet to gateway in response to Op9")
s.wsMutex.Lock()
err = s.wsConn.WriteJSON(handshakeOp{2, handshakeData{s.Token, handshakeProperties{runtime.GOOS, "Discordgo v" + VERSION, "", "", ""}, 250, s.Compress}})
s.wsMutex.Unlock()
if err != nil {
s.log(LogWarning, "error sending gateway identify packet, %s, %s", s.gateway, err)
return
Expand Down Expand Up @@ -468,7 +477,9 @@ func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool) (voice *Voi

// Send the request to Discord that we want to join the voice channel
data := voiceChannelJoinOp{4, voiceChannelJoinData{&gID, &cID, mute, deaf}}
s.wsMutex.Lock()
err = s.wsConn.WriteJSON(data)
s.wsMutex.Unlock()
if err != nil {
s.log(LogInformational, "Deleting VoiceConnection %s", gID)
delete(s.VoiceConnections, gID)
Expand Down

0 comments on commit e9e9ef8

Please sign in to comment.