diff --git a/cmd/daemon/main.go b/cmd/daemon/main.go index 1cce248..2857e9d 100644 --- a/cmd/daemon/main.go +++ b/cmd/daemon/main.go @@ -18,6 +18,7 @@ func main() { dataDir := flag.String("data-dir", "~/.waste", "path to identity/config directory") alias := flag.String("alias", "anon", "display name shown to peers (advisory only)") ipcPort := flag.Int("ipc-port", 17337, "port for local IPC (UI connects here)") + wsPort := flag.Int("ws-port", 0, "port for WebSocket IPC (web UI); 0 = disabled") anchorURL := flag.String("anchor", "", "anchor WebSocket URL, e.g. ws://your-vps:17339/ws") shareDir := flag.String("share-dir", "", "directory to share with peers on the network") joinInvite := flag.String("join", "", "waste: invite string — sets anchor URL and auto-joins the network on startup") @@ -81,6 +82,14 @@ func main() { } } + if *wsPort != 0 { + go func() { + if err := ipc.RunWS(mgr, *wsPort); err != nil { + log.Fatalf("ipc ws: %v", err) + } + }() + } + if err := ipc.Run(mgr, *ipcPort); err != nil { log.Fatalf("ipc: %v", err) } diff --git a/internal/ipc/ipc.go b/internal/ipc/ipc.go index 7accdda..e87eb75 100644 --- a/internal/ipc/ipc.go +++ b/internal/ipc/ipc.go @@ -14,14 +14,37 @@ import ( "fmt" "log" "net" + "net/http" "time" + "nhooyr.io/websocket" + "github.com/waste-go/internal/crypto" "github.com/waste-go/internal/invite" "github.com/waste-go/internal/netmgr" "github.com/waste-go/internal/proto" ) +// RunWS starts a WebSocket IPC server on 127.0.0.1:wsPort. +// Each WebSocket connection gets the same handleClient treatment as TCP. +// The OriginPatterns option allows connections from local dev servers. +func RunWS(mgr *netmgr.Manager, wsPort int) error { + addr := fmt.Sprintf("127.0.0.1:%d", wsPort) + log.Printf("ipc: WS listening on %s", addr) + return http.ListenAndServe(addr, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + conn, err := websocket.Accept(w, r, &websocket.AcceptOptions{ + OriginPatterns: []string{"localhost:*", "127.0.0.1:*"}, + }) + if err != nil { + log.Printf("ipc: ws accept: %v", err) + return + } + log.Printf("ipc: WS client connected") + nc := websocket.NetConn(r.Context(), conn, websocket.MessageText) + handleClient(nc, mgr) + })) +} + // Run starts the IPC listener. Blocks until the listener fails. func Run(mgr *netmgr.Manager, port int) error { addr := fmt.Sprintf("127.0.0.1:%d", port)