package connection import ( "context" "log" "mchess_server/types" "github.com/google/uuid" gorillaws "github.com/gorilla/websocket" ) type Connection struct { ID uuid.UUID ws *gorillaws.Conn ctx context.Context rxBuffer *MessageBuffer txBuffer *MessageBuffer disconnectCallback func() forColor types.ChessColor } func NewConnection(options ...func(*Connection)) *Connection { connection := Connection{ ID: uuid.New(), rxBuffer: newMessageBuffer(100), txBuffer: newMessageBuffer(100), } for _, option := range options { option(&connection) } return &connection } func WithWebsocket(ws *gorillaws.Conn) func(*Connection) { return func(c *Connection) { c.ws = ws } } func WithContext(ctx context.Context) func(*Connection) { return func(c *Connection) { c.ctx = ctx } } func WithDisconnectCallback(cb func()) func(*Connection) { return func(c *Connection) { if cb != nil { c.disconnectCallback = cb } } } func (conn *Connection) SetForColor(color types.ChessColor) { conn.forColor = color } func (conn *Connection) SetDisconnectCallback(cb func()) { conn.disconnectCallback = cb } func (conn *Connection) HasWebsocketConnection() bool { return conn.ws != nil } func (conn *Connection) readFromRxBuffer() { for { _, msg, err := conn.ws.ReadMessage() if err != nil { conn.logConnection("while reading from websocket: %w", err) conn.Close("") conn.txBuffer.Insert("we do this to make txBuffer.Get() return") return } conn.rxBuffer.Insert(string(msg)) } } func (conn *Connection) writeTxBuffer() { for { msg := conn.txBuffer.Get() if conn.ws == nil { return } err := conn.ws.WriteMessage(gorillaws.TextMessage, []byte(msg)) if err != nil { conn.logConnection("while writing to websocket: %w", err) return } } } func (conn *Connection) SetWebsocketConnection(ws *gorillaws.Conn) { if ws == nil { conn.logConnection("ERROR: setting ws = null") return } conn.ws = ws go conn.readFromRxBuffer() go conn.writeTxBuffer() defer conn.logConnection("websocket connection set") } func (conn *Connection) unsetWebsocketConnection() { conn.logConnection("websocket connection unset") conn.ws = nil } func (conn *Connection) Write(msg string) { conn.logConnection("Writing message: ", string(msg)) conn.txBuffer.Insert(msg) } func (conn *Connection) Read() []byte { msg := conn.rxBuffer.Get() return []byte(msg) } func (conn *Connection) Close(msg string) { conn.logConnection("closing websocket connection") conn.ws.WriteMessage(gorillaws.TextMessage, []byte(msg)) conn.ws.Close() conn.ws = nil } func (con *Connection) logConnection(v ...any) { log.Println("on connection: ", con.ID) log.Println("for color: ", con.forColor.String(), v) }