This change switches GARM to the new structured logging standard library. This will allow us to set log levels and reduce some of the log spam. Given that we introduced new knobs to tweak logging, the number of config options for logging now warrants it's own section. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
112 lines
2.5 KiB
Go
112 lines
2.5 KiB
Go
package websocket
|
|
|
|
import (
|
|
"log/slog"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
const (
|
|
// Time allowed to write a message to the peer.
|
|
writeWait = 10 * time.Second
|
|
|
|
// Time allowed to read the next pong message from the peer.
|
|
pongWait = 60 * time.Second
|
|
|
|
// Send pings to peer with this period. Must be less than pongWait.
|
|
pingPeriod = (pongWait * 9) / 10
|
|
|
|
// Maximum message size allowed from peer.
|
|
maxMessageSize = 1024
|
|
)
|
|
|
|
func NewClient(conn *websocket.Conn, hub *Hub) (*Client, error) {
|
|
clientID := uuid.New()
|
|
return &Client{
|
|
id: clientID.String(),
|
|
conn: conn,
|
|
hub: hub,
|
|
send: make(chan []byte, 100),
|
|
}, nil
|
|
}
|
|
|
|
type Client struct {
|
|
id string
|
|
conn *websocket.Conn
|
|
// Buffered channel of outbound messages.
|
|
send chan []byte
|
|
|
|
hub *Hub
|
|
}
|
|
|
|
func (c *Client) Go() {
|
|
go c.clientReader()
|
|
go c.clientWriter()
|
|
}
|
|
|
|
// clientReader waits for options changes from the client. The client can at any time
|
|
// change the log level and binary name it watches.
|
|
func (c *Client) clientReader() {
|
|
defer func() {
|
|
c.hub.unregister <- c
|
|
c.conn.Close()
|
|
}()
|
|
c.conn.SetReadLimit(maxMessageSize)
|
|
if err := c.conn.SetReadDeadline(time.Now().Add(pongWait)); err != nil {
|
|
slog.With(slog.Any("error", err)).Error("failed to set read deadline")
|
|
}
|
|
c.conn.SetPongHandler(func(string) error {
|
|
if err := c.conn.SetReadDeadline(time.Now().Add(pongWait)); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
for {
|
|
mt, _, err := c.conn.ReadMessage()
|
|
if err != nil {
|
|
break
|
|
}
|
|
if mt == websocket.CloseMessage {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// clientWriter
|
|
func (c *Client) clientWriter() {
|
|
ticker := time.NewTicker(pingPeriod)
|
|
defer func() {
|
|
ticker.Stop()
|
|
c.conn.Close()
|
|
}()
|
|
for {
|
|
select {
|
|
case message, ok := <-c.send:
|
|
if err := c.conn.SetWriteDeadline(time.Now().Add(writeWait)); err != nil {
|
|
slog.With(slog.Any("error", err)).Error("failed to set write deadline")
|
|
}
|
|
if !ok {
|
|
// The hub closed the channel.
|
|
if err := c.conn.WriteMessage(websocket.CloseMessage, []byte{}); err != nil {
|
|
slog.With(slog.Any("error", err)).Error("failed to write message")
|
|
}
|
|
return
|
|
}
|
|
|
|
if err := c.conn.WriteMessage(websocket.TextMessage, message); err != nil {
|
|
slog.With(slog.Any("error", err)).Error("error sending message")
|
|
return
|
|
}
|
|
case <-ticker.C:
|
|
if err := c.conn.SetWriteDeadline(time.Now().Add(writeWait)); err != nil {
|
|
slog.With(slog.Any("error", err)).Error("failed to set write deadline")
|
|
}
|
|
if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|