diff --git a/discord.go b/discord.go index 6014d87..624aeb9 100644 --- a/discord.go +++ b/discord.go @@ -117,20 +117,3 @@ func New(args ...interface{}) (s *Session, err error) { return } - -// OpenAndListen is a helper method that opens the websocket connection, -// does the required handshake and then immediately begins listening. -// This is the preferred way to start listening for events and is safe -// to be called inside an OnDisconnect handler. -func (s *Session) OpenAndListen() (err error) { - // Open websocket connection. - err = s.Open() - if err != nil { - return - } - - // Listen for events. - go s.Listen() - - return -} diff --git a/discord_test.go b/discord_test.go index 2dde3f7..deed4f4 100644 --- a/discord_test.go +++ b/discord_test.go @@ -199,8 +199,8 @@ func TestOpenClose(t *testing.T) { t.Fatalf("TestClose, New(envToken) returned error: %+v", err) } - if err = d.OpenAndListen(); err != nil { - t.Fatalf("TestClose, d.OpenAndListen failed: %+v", err) + if err = d.Open(); err != nil { + t.Fatalf("TestClose, d.Open failed: %+v", err) } if err = d.Close(); err != nil { diff --git a/examples/api_basic/api_basic.go b/examples/api_basic/api_basic.go index 8c8fcd2..aea4e56 100644 --- a/examples/api_basic/api_basic.go +++ b/examples/api_basic/api_basic.go @@ -40,9 +40,6 @@ func main() { fmt.Println(err) } - // Listen for events. - go dg.Listen() - // Simple way to keep program running until any key press. var input string fmt.Scanln(&input) diff --git a/examples/new_basic/new_basic.go b/examples/new_basic/new_basic.go index 752ce78..43492ec 100644 --- a/examples/new_basic/new_basic.go +++ b/examples/new_basic/new_basic.go @@ -32,7 +32,7 @@ func main() { dg.OnMessageCreate = messageCreate // Open the websocket and begin listening. - dg.OpenAndListen() + dg.Open() // Simple way to keep program running until any key press. var input string diff --git a/wsapi.go b/wsapi.go index b984e18..51432a3 100644 --- a/wsapi.go +++ b/wsapi.go @@ -70,6 +70,11 @@ func (s *Session) Open() (err error) { return } + // Create listening outside of listen, as it needs to happen inside the mutex + // lock. + s.listening = make(chan interface{}) + go s.listen(s.listening) + s.Unlock() if s.OnConnect != nil { @@ -105,6 +110,29 @@ func (s *Session) Close() (err error) { return } +// listen polls the websocket connection for events, it will stop when +// the listening channel is closed, or an error occurs. +func (s *Session) listen(listening <-chan interface{}) { + for { + messageType, message, err := s.wsConn.ReadMessage() + if err != nil { + // There has been an error reading, Close() the websocket so that + // OnDisconnect is fired. + s.Close() + return + } + + select { + case <-listening: + return + default: + go s.event(messageType, message) + } + } + + return +} + type updateStatusGame struct { Name string `json:"name"` } @@ -142,46 +170,6 @@ func (s *Session) UpdateStatus(idle int, game string) (err error) { return } -// Listen starts listening to the websocket connection for events. -func (s *Session) Listen() (err error) { - s.RLock() - - if s.wsConn == nil { - s.RUnlock() - return errors.New("No websocket connection exists.") - } - if s.listening != nil { - s.RUnlock() - return errors.New("Already listening to websocket.") - } - - s.listening = make(chan interface{}) - - s.RUnlock() - - // Keep a reference, as s.listening can be nilled out. - listening := s.listening - - for { - messageType, message, err1 := s.wsConn.ReadMessage() - if err1 != nil { - err = err1 - // Defer so we get better log ordering. - defer s.Close() - return fmt.Errorf("Websocket Listen Error", err) - } - - select { - case <-listening: - return - default: - go s.event(messageType, message) - } - } - - return -} - // Not sure how needed this is and where it would be best to call it. // somewhere.