0

Websocket fixes (#461)

* Bump api spec version

* Do not panic on cpu monitoring error

* Centralize the socket disconnect logic and fire it also when socket errors occur. Hopefully closes #421
This commit is contained in:
Gabe Kangas 2020-12-21 19:42:47 -08:00 committed by GitHub
parent eab45c7e92
commit e558c549d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 15 deletions

View File

@ -72,7 +72,7 @@ func (c *Client) Write(msg models.ChatMessage) {
select {
case c.ch <- msg:
default:
_server.remove(c)
_server.removeClient(c)
_server.err(fmt.Errorf("client %s is disconnected", c.ClientID))
}
}
@ -96,28 +96,33 @@ func (c *Client) listenWrite() {
case msg := <-c.pingch:
err := websocket.JSON.Send(c.ws, msg)
if err != nil {
log.Errorln(err)
c.handleClientSocketError(err)
}
// send message to the client
case msg := <-c.ch:
err := websocket.JSON.Send(c.ws, msg)
if err != nil {
log.Errorln(err)
c.handleClientSocketError(err)
}
case msg := <-c.usernameChangeChannel:
err := websocket.JSON.Send(c.ws, msg)
if err != nil {
log.Errorln(err)
c.handleClientSocketError(err)
}
// receive done request
case <-c.doneCh:
_server.remove(c)
_server.removeClient(c)
c.doneCh <- true // for listenRead method
return
}
}
}
func (c *Client) handleClientSocketError(err error) {
log.Errorln("Websocket client error: ", err.Error())
_server.removeClient(c)
}
// Listen read request via channel.
func (c *Client) listenRead() {
for {
@ -136,7 +141,7 @@ func (c *Client) listenRead() {
if err == io.EOF {
c.doneCh <- true
} else {
log.Errorln(err)
c.handleClientSocketError(err)
}
return
}

View File

@ -3,6 +3,7 @@ package chat
import (
"fmt"
"net/http"
"sync"
"time"
log "github.com/sirupsen/logrus"
@ -16,6 +17,8 @@ var (
_server *server
)
var l = sync.Mutex{}
// Server represents the server which handles the chat.
type server struct {
Clients map[string]*Client
@ -74,7 +77,7 @@ func (s *server) onConnection(ws *websocket.Conn) {
client := NewClient(ws)
defer func() {
log.Tracef("The client was connected for %s and sent %d messages (%s)", time.Since(client.ConnectedAt), client.MessageCount, client.ClientID)
s.removeClient(client)
if err := ws.Close(); err != nil {
s.errCh <- err
@ -96,18 +99,20 @@ func (s *server) Listen() {
select {
// add new a client
case c := <-s.addCh:
l.Lock()
s.Clients[c.socketID] = c
l.Unlock()
s.listener.ClientAdded(c.GetViewerClientFromChatClient())
s.sendWelcomeMessageToClient(c)
// remove a client
case c := <-s.delCh:
delete(s.Clients, c.socketID)
s.listener.ClientRemoved(c.socketID)
s.removeClient(c)
case msg := <-s.sendAllCh:
// message was received from a client and should be sanitized, validated
// and distributed to other clients.
case msg := <-s.sendAllCh:
//
// Will turn markdown into html, sanitize user-supplied raw html
// and standardize this message into something safe we can send everyone else.
msg.RenderAndSanitizeMessageBody()
@ -129,6 +134,19 @@ func (s *server) Listen() {
}
}
func (s *server) removeClient(c *Client) {
l.Lock()
if _, ok := s.Clients[c.socketID]; ok {
delete(s.Clients, c.socketID)
s.listener.ClientRemoved(c.socketID)
log.Tracef("The client was connected for %s and sent %d messages (%s)", time.Since(c.ConnectedAt), c.MessageCount, c.ClientID)
}
l.Unlock()
}
func (s *server) sendWelcomeMessageToClient(c *Client) {
go func() {
// Add an artificial delay so people notice this message come in.

View File

@ -6,6 +6,8 @@ import (
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/disk"
"github.com/shirou/gopsutil/mem"
log "github.com/sirupsen/logrus"
)
// Max number of metrics we want to keep.
@ -18,7 +20,8 @@ func collectCPUUtilization() {
v, err := cpu.Percent(0, false)
if err != nil {
panic(err)
log.Errorln(err)
return
}
metricValue := timestampedValue{time.Now(), int(v[0])}

View File

@ -7,8 +7,8 @@ config:
maxErrorRate: 1
phases:
- duration: 30
arrivalRate: 10
- duration: 100
arrivalRate: 15
ws:
subprotocols:
- json
@ -21,4 +21,4 @@ scenarios:
flow:
- function: "createTestMessageObject"
- send: "{{ data }}"
- think: 5
- think: 10