Gateway working, beta
This commit is contained in:
107
ws/websocket.go
107
ws/websocket.go
@@ -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})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user