111 lines
2.2 KiB
Go
111 lines
2.2 KiB
Go
package ws
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log/slog"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
type WebsocketGateway struct {
|
|
port int
|
|
apiKey string
|
|
bodySizeBytes int64
|
|
|
|
upgrader websocket.Upgrader
|
|
|
|
registry *Registry
|
|
|
|
logger *slog.Logger
|
|
closeFn func() error
|
|
}
|
|
|
|
//
|
|
|
|
type Registry struct {
|
|
mu sync.RWMutex
|
|
entries map[string]*ChannelEntry
|
|
queueCap int
|
|
|
|
botMu sync.Mutex
|
|
bot *ConnWrapper
|
|
}
|
|
|
|
type ConnWrapper struct {
|
|
Conn *websocket.Conn
|
|
ServerID string // set for mods (the server_id)
|
|
LastSeen time.Time
|
|
}
|
|
|
|
type BoundedQueue struct {
|
|
mu sync.Mutex
|
|
buf []GatewayMessageOut
|
|
start int
|
|
length int
|
|
capacity int
|
|
}
|
|
|
|
type ChannelEntry struct {
|
|
mu sync.Mutex
|
|
Channel string
|
|
Mod *ConnWrapper
|
|
Queue *BoundedQueue
|
|
}
|
|
|
|
//
|
|
|
|
type User struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type Destination struct {
|
|
ID string `json:"channel_id,omitempty"`
|
|
}
|
|
|
|
type GatewayMessageIn struct {
|
|
Type string
|
|
ID string `json:"id"`
|
|
MsgID string `json:"msg_id"`
|
|
Destination Destination `json:"destination,omitempty"`
|
|
Author User `json:"author"`
|
|
Content string `json:"content"`
|
|
Meta map[string]interface{} `json:"meta,omitempty"`
|
|
Ts time.Time `json:"ts,omitempty"`
|
|
ReceivedAt time.Time `json:"-"`
|
|
}
|
|
|
|
type GatewayMessageOut struct {
|
|
Type string `json:"type"`
|
|
ID string `json:"channel_id,omitempty"`
|
|
Author User `json:"author"`
|
|
Content string `json:"content"`
|
|
Meta map[string]interface{} `json:"meta,omitempty"`
|
|
Ts time.Time `json:"ts,omitempty"`
|
|
ReceivedAt time.Time `json:"received_at"`
|
|
ForwardedAt time.Time `json:"forwarded_at"`
|
|
}
|
|
|
|
type GatewayAck struct {
|
|
Status string `json:"status"`
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
//
|
|
|
|
type Handshake struct {
|
|
Type string `json:"type"` // "mod" or "bot"
|
|
Data json.RawMessage `json:"data"`
|
|
}
|
|
|
|
type ModHandshake struct {
|
|
ServerID string `json:"server_id"`
|
|
ChannelID string `json:"channel_id"`
|
|
}
|
|
|
|
type BotHandshake struct {
|
|
BotID string `json:"bot_id"`
|
|
}
|