Skip to content

Commit

Permalink
fix the issue with the 'ReadMessage' thread not exiting when 'stopCh'…
Browse files Browse the repository at this point in the history
… is triggered
  • Loading branch information
jackjohn committed Oct 15, 2024
1 parent d37282f commit 6834c14
Showing 1 changed file with 20 additions and 21 deletions.
41 changes: 20 additions & 21 deletions websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,36 +66,19 @@ var wsServe = func(cfg *WsConfig, handler WsHandler, errHandler ErrHandler) (don
c.SetReadLimit(655350)
doneCh = make(chan struct{})
stopCh = make(chan struct{})

go func() {
// This function will exit either on error from
// websocket.Conn.ReadMessage or when the stopC channel is
// closed by the client.
defer close(doneCh)
defer close(stopCh)
if WebsocketKeepalive {
keepAlive(c, WebsocketTimeout)
}
// Wait for the stopC channel to be closed. We do that in a
// separate goroutine because ReadMessage is a blocking
// operation.
silent := false
go func() {
for {
_, message, err := c.ReadMessage()
if err != nil {
if !silent {
errHandler(err)
}
stopCh <- struct{}{}
return
}
handler(message)
}
}()
// Separate goroutine to handle message reading
go readMessages(c, handler, errHandler, stopCh)

for {
select {
case <-stopCh:
silent = true
return
case <-doneCh:
}
Expand All @@ -104,6 +87,22 @@ var wsServe = func(cfg *WsConfig, handler WsHandler, errHandler ErrHandler) (don
return
}

func readMessages(c *websocket.Conn, handler WsHandler, errHandler ErrHandler, stopCh chan struct{}) {
for {
select {
case <-stopCh:
return
default:
_, message, err := c.ReadMessage()
if err != nil {
errHandler(err)
return
}
handler(message)
}
}
}

func keepAlive(c *websocket.Conn, timeout time.Duration) {
ticker := time.NewTicker(timeout)

Expand Down

0 comments on commit 6834c14

Please sign in to comment.