garm/websocket/client.go
Gabriel Adrian Samfira b354cedf7e
Fixed a bunch of linting issues
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2023-01-20 22:21:22 +02:00

112 lines
2.4 KiB
Go

package websocket
import (
"log"
"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 {
log.Printf("failed to set read deadline: %s", err)
}
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 {
log.Printf("failed to set write deadline: %s", err)
}
if !ok {
// The hub closed the channel.
if err := c.conn.WriteMessage(websocket.CloseMessage, []byte{}); err != nil {
log.Printf("failed to write message: %s", err)
}
return
}
if err := c.conn.WriteMessage(websocket.TextMessage, message); err != nil {
log.Printf("error sending message: %v", err)
return
}
case <-ticker.C:
if err := c.conn.SetWriteDeadline(time.Now().Add(writeWait)); err != nil {
log.Printf("failed to set write deadline: %s", err)
}
if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
return
}
}
}
}