From c6fbf3e427ab8fbc26745f434490d0306a90f759 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Wed, 19 Nov 2025 21:42:43 -0600 Subject: [PATCH] add udp-client --- config.json | 14 ++++----- udp-client.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 udp-client.go diff --git a/config.json b/config.json index b3da26f..aa134b1 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "modules": [ { - "id": "tcp1", + "id": "tcp", "type": "net.tcp.server", "params": { "port": 8000, @@ -9,18 +9,18 @@ } }, { - "id": "tcp2", - "type": "net.tcp.server", + "id": "udp", + "type": "net.udp.client", "params": { - "port": 8001, - "framing": "LF" + "host": "127.0.0.1", + "port": 8888 } } ], "routes": [ { - "input": "tcp1", - "output": "tcp2" + "input": "tcp", + "output": "udp" } ] } diff --git a/udp-client.go b/udp-client.go new file mode 100644 index 0000000..5e50f9a --- /dev/null +++ b/udp-client.go @@ -0,0 +1,85 @@ +package showbridge + +import ( + "context" + "fmt" + "log/slog" + "net" +) + +type UDPClient struct { + config ModuleConfig + Host string + Port uint16 + conn net.Conn + router *Router +} + +func init() { + RegisterModule(ModuleRegistration{ + Type: "net.udp.client", + New: func(config ModuleConfig) (Module, error) { + params := config.Params + host, ok := params["host"] + + if !ok { + return nil, fmt.Errorf("udp client requires a host parameter") + } + + hostString, ok := host.(string) + + if !ok { + return nil, fmt.Errorf("udp client host must be uint16") + } + + port, ok := params["port"] + if !ok { + return nil, fmt.Errorf("udp client requires a port parameter") + } + + portNum, ok := port.(float64) + + if !ok { + return nil, fmt.Errorf("udp client port must be uint16") + } + + return &UDPClient{Host: hostString, Port: uint16(portNum), config: config}, nil + }, + }) +} + +func (uc *UDPClient) Id() string { + return uc.config.Id +} + +func (uc *UDPClient) Type() string { + return uc.config.Type +} + +func (uc *UDPClient) RegisterRouter(router *Router) { + slog.Debug("registering router", "id", uc.config.Id) + uc.router = router +} + +func (uc *UDPClient) Run(ctx context.Context) error { + client, err := net.Dial("udp", fmt.Sprintf(":%d", uc.Port)) + if err != nil { + return err + } + + uc.conn = client + <-ctx.Done() + return nil +} + +func (uc *UDPClient) Output(payload any) error { + if uc.conn != nil { + payloadBytes, ok := payload.([]byte) + if !ok { + return fmt.Errorf("udp-client is only able to output bytes") + } + _, err := uc.conn.Write(payloadBytes) + return err + } + return nil +}