Browse Source

Get rid of Listen.

Chris Rhodes 9 years ago
parent
commit
8b39278c3e
5 changed files with 31 additions and 63 deletions
  1. 0 17
      discord.go
  2. 2 2
      discord_test.go
  3. 0 3
      examples/api_basic/api_basic.go
  4. 1 1
      examples/new_basic/new_basic.go
  5. 28 40
      wsapi.go

+ 0 - 17
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
-}

+ 2 - 2
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 {

+ 0 - 3
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)

+ 1 - 1
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

+ 28 - 40
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.