0

Fix a memory leak with the chat aspect. (#23)

Essentially, the for loop wasn't being returned out
of and that caused the read listener to never be
let up and released to the gc
This commit is contained in:
Bradley Hilton 2020-06-23 01:52:50 -05:00 committed by GitHub
parent 487bd12444
commit fe96739f60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 26 deletions

View File

@ -3,6 +3,7 @@ package chat
import (
"fmt"
"io"
"time"
log "github.com/sirupsen/logrus"
"golang.org/x/net/websocket"
@ -15,6 +16,9 @@ const channelBufSize = 100
//Client represents a chat client.
type Client struct {
ConnectedAt time.Time
MessageCount int
id string
ws *websocket.Conn
server *Server
@ -39,7 +43,7 @@ func NewClient(ws *websocket.Conn, server *Server) *Client {
pingch := make(chan models.PingMessage)
clientID := utils.GenerateClientIDFromRequest(ws.Request())
return &Client{clientID, ws, server, ch, pingch, doneCh}
return &Client{time.Now(), 0, clientID, ws, server, ch, pingch, doneCh}
}
//GetConnection gets the connection for the client
@ -106,9 +110,11 @@ func (c *Client) listenRead() {
if err := websocket.JSON.Receive(c.ws, &msg); err == io.EOF {
c.doneCh <- true
return
} else if err != nil {
c.server.Err(err)
} else {
c.MessageCount++
c.server.SendToAll(msg)
}
}

View File

@ -5,19 +5,19 @@ import (
"net/http"
"time"
log "github.com/sirupsen/logrus"
"golang.org/x/net/websocket"
"github.com/gabek/owncast/core"
"github.com/gabek/owncast/models"
log "github.com/sirupsen/logrus"
"golang.org/x/net/websocket"
)
//Server represents the server which handles the chat
type Server struct {
Pattern string
Messages []models.ChatMessage
Clients map[string]*Client
pattern string
addCh chan *Client
delCh chan *Client
sendAllCh chan models.ChatMessage
@ -27,7 +27,7 @@ type Server struct {
}
//NewServer creates a new chat server
func NewServer(pattern string) *Server {
func NewServer() *Server {
messages := []models.ChatMessage{}
clients := make(map[string]*Client)
addCh := make(chan *Client)
@ -46,9 +46,9 @@ func NewServer(pattern string) *Server {
messages = append(messages, models.ChatMessage{"Blathers", "Blathers is an owl with brown feathers. His face is white and he has a yellow beak. His arms are wing shaped and he has yellow talons. His eyes are very big with small black irises. He also has big pink cheek circles on his cheeks. His belly appears to be checkered in diamonds with light brown and white squares, similar to an argyle vest, which is traditionally associated with academia. His green bowtie further alludes to his academic nature.", "https://vignette.wikia.nocookie.net/animalcrossing/images/b/b3/NH-character-Blathers.png/revision/latest?cb=20200229053519", "demo-message-6", "ChatMessage"})
server := &Server{
pattern,
messages,
clients,
"/entry", //hardcoded due to the UI requiring this and it is not configurable
addCh,
delCh,
sendAllCh,
@ -116,26 +116,27 @@ func (s *Server) ping() {
}
}
// Listen and serve.
// It serves client connection and broadcast request.
func (s *Server) Listen() {
// websocket handler
onConnected := func(ws *websocket.Conn) {
func (s *Server) onConnection(ws *websocket.Conn) {
client := NewClient(ws, s)
defer func() {
err := ws.Close()
if err != nil {
log.Printf("The client was connected for %s and sent %d messages (%s)", time.Since(client.ConnectedAt), client.MessageCount, client.id)
if err := ws.Close(); err != nil {
s.errCh <- err
}
}()
client := NewClient(ws, s)
s.Add(client)
client.Listen()
}
http.Handle(s.Pattern, websocket.Handler(onConnected))
// Listen and serve.
// It serves client connection and broadcast request.
func (s *Server) Listen() {
http.Handle(s.pattern, websocket.Handler(s.onConnection))
log.Printf("Starting the websocket listener on: %s", s.Pattern)
log.Printf("Starting the websocket listener on: %s", s.pattern)
for {
select {

View File

@ -15,7 +15,7 @@ import (
//Start starts the router for the http, ws, and rtmp
func Start() error {
// websocket server
chatServer := chat.NewServer("/entry")
chatServer := chat.NewServer()
go chatServer.Listen()
// start the rtmp server

View File

@ -66,9 +66,9 @@ function setupWebsocket() {
// Uncomment to point to somewhere other than goth.land
const protocol = location.protocol == "https:" ? "wss" : "ws"
// var ws = new WebSocket(protocol + "://" + location.host + "/entry")
var ws = new WebSocket(protocol + "://" + location.host + "/entry")
var ws = new WebSocket("wss://goth.land/entry")
// var ws = new WebSocket("wss://goth.land/entry")
ws.onmessage = (e) => {
const model = JSON.parse(e.data)