mchess-server/connection/type.go

138 lines
2.8 KiB
Go

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)
}