Gateway working, beta

This commit is contained in:
2025-12-07 17:11:37 +01:00
parent de03c1fe3d
commit 3d6774586e
13 changed files with 616 additions and 506 deletions

View File

@@ -4,9 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"homestead/homestead_gateway/util/cache"
"homestead/homestead_gateway/util/config"
"homestead/homestead_gateway/util/queue"
"log/slog"
"net"
"net/http"
@@ -19,13 +17,11 @@ import (
func NewWebsocketGateway(cfg config.GatewayConfig, logger *slog.Logger, closefn func() error) *WebsocketGateway {
return &WebsocketGateway{
logger: logger,
closeFn: closefn,
port: cfg.HttpPort,
apiKey: cfg.Websocket,
cache: cache.NewCache(),
queue: queue.NewQueue[GatewayMessageOut](32),
conns: cache.NewConnectionCache(),
logger: logger,
closeFn: closefn,
port: cfg.HttpPort,
apiKey: cfg.Websocket,
registry: NewRegistry(32),
upgrader: websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
@@ -184,9 +180,9 @@ func (wsg *WebsocketGateway) Serve(ctx context.Context, listenAddr string) error
// }
//}
func (wsg *WebsocketGateway) read(conn *websocket.Conn, meta cache.ConnectionMetaData, _type string) {
func (wsg *WebsocketGateway) read(conn *websocket.Conn, _type, channelId string) {
defer func() {
wsg.unregisterConn(conn, meta, _type)
wsg.unregisterConn(conn, _type, channelId)
wsg.logger.Info("Client disconnected.", "remote", conn.RemoteAddr().String())
}()
@@ -235,70 +231,16 @@ func (wsg *WebsocketGateway) read(conn *websocket.Conn, meta cache.ConnectionMet
continue
}
var ok bool
var destConn *websocket.Conn
switch message.Type {
case "mod":
if wsg.bot != nil {
ok = true
destConn = wsg.bot
} else {
ok = false
}
case "bot":
var id string
id, ok = wsg.cache.GetByChannelId(message.ID)
if ok {
var dest *websocket.Conn
dest, _, ok = wsg.conns.GetById(id)
if ok {
destConn = dest
} else {
wsg.sendWebsocketError(conn, "Internal Server Error", 500, true)
wsg.logger.Error("Invalid cache structure.", "remote", conn.RemoteAddr().String(), "id", id)
return
}
}
default:
panic("invalid message type")
}
if ok {
if destConn == nil {
wsg.sendWebsocketError(conn, "Internal Server Error", 500, true)
wsg.logger.Error("Destination connection unavailable.", "remote", conn.RemoteAddr().String())
return
}
err = wsg.sendWebsocketResponse(destConn, GatewayMessageOut{
Type: message.Type,
ID: message.Destination.ID,
Author: message.Author,
Content: message.Content,
Meta: message.Meta,
Ts: message.Ts,
ReceivedAt: message.ReceivedAt,
ForwardedAt: time.Now().UTC(),
})
if err != nil {
_ = wsg.sendWebsocketResponse(conn, GatewayAck{Status: "failed", Type: message.Type})
wsg.logger.Error("Failed to forward message.", "remote", conn.RemoteAddr().String(), "err", err)
continue
}
_ = wsg.sendWebsocketResponse(conn, GatewayAck{Status: "completed", Type: message.Type})
continue
}
if message.Type == "mod" {
wsg.cache.Set(message.ID, message.Destination.ID)
var outID string
if _type == "mod" {
outID = channelId
} else {
outID = message.ID
}
out := GatewayMessageOut{
Type: message.Type,
ID: message.Destination.ID,
ID: outID,
Author: message.Author,
Content: message.Content,
Meta: message.Meta,
@@ -307,13 +249,28 @@ func (wsg *WebsocketGateway) read(conn *websocket.Conn, meta cache.ConnectionMet
ForwardedAt: time.Now().UTC(),
}
queued := wsg.queue.Enqueue(out)
if !queued {
delivered, queued, err := wsg.registry.Send(out.ID, out, func(c *websocket.Conn, m GatewayMessageOut) error {
_ = c.SetWriteDeadline(time.Now().Add(5 * time.Second))
return c.WriteJSON(m)
})
if err != nil {
wsg.logger.Error("registry send error", "err", err)
_ = wsg.sendWebsocketResponse(conn, GatewayAck{Status: "failed", Type: message.Type})
wsg.logger.Warn("Failed to queue message.", "remote", conn.RemoteAddr().String())
continue
}
_ = wsg.sendWebsocketResponse(conn, GatewayAck{Status: "queued", Type: message.Type})
if delivered {
_ = wsg.sendWebsocketResponse(conn, GatewayAck{Status: "completed", Type: message.Type})
continue
}
if queued {
_ = wsg.sendWebsocketResponse(conn, GatewayAck{Status: "queued", Type: message.Type})
continue
}
_ = wsg.sendWebsocketResponse(conn, GatewayAck{Status: "failed", Type: message.Type})
}
}