summaryrefslogtreecommitdiffstats
path: root/cmd/relay
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-02-13 18:26:53 -0800
committerbndw <ben@bdw.to>2026-02-13 18:26:53 -0800
commit83876eae868bd1e4fb6b9a823a6e8173919f290d (patch)
treef754bcb8b10337db34f6f36ba3d094e53c1bb808 /cmd/relay
parent3481c3273f8764bd0a0ab51183dc57f592fb616c (diff)
feat: add Connect (gRPC over HTTP/JSON) support
Connect integration: - Buf Connect codegen added to buf.gen.yaml - Connect handler wraps gRPC server - Serves on same port as WebSocket (:8080) - HTTP/2 with h2c for cleartext HTTP/2 Now serving THREE protocols: 1. gRPC (native) on :50051 - binary, high performance 2. Connect on :8080/nostr.v1.NostrRelay/* - HTTP/JSON, browser compatible 3. WebSocket on :8080/ - Nostr standard protocol All three protocols share: - Same storage layer - Same subscription manager - Same validation logic Browser-friendly! Call gRPC methods with fetch() or curl.
Diffstat (limited to 'cmd/relay')
-rw-r--r--cmd/relay/main.go18
1 files changed, 16 insertions, 2 deletions
diff --git a/cmd/relay/main.go b/cmd/relay/main.go
index 53296b9..9cf6ad6 100644
--- a/cmd/relay/main.go
+++ b/cmd/relay/main.go
@@ -11,9 +11,14 @@ import (
11 11
12 "context" 12 "context"
13 13
14 "connectrpc.com/connect"
15 "golang.org/x/net/http2"
16 "golang.org/x/net/http2/h2c"
14 "google.golang.org/grpc" 17 "google.golang.org/grpc"
15 18
16 pb "northwest.io/nostr-grpc/api/nostr/v1" 19 pb "northwest.io/nostr-grpc/api/nostr/v1"
20 "northwest.io/nostr-grpc/api/nostr/v1/nostrv1connect"
21 connecthandler "northwest.io/nostr-grpc/internal/handler/connect"
17 grpchandler "northwest.io/nostr-grpc/internal/handler/grpc" 22 grpchandler "northwest.io/nostr-grpc/internal/handler/grpc"
18 wshandler "northwest.io/nostr-grpc/internal/handler/websocket" 23 wshandler "northwest.io/nostr-grpc/internal/handler/websocket"
19 "northwest.io/nostr-grpc/internal/storage" 24 "northwest.io/nostr-grpc/internal/storage"
@@ -39,7 +44,14 @@ func main() {
39 grpcHandler := grpchandler.NewServer(store) 44 grpcHandler := grpchandler.NewServer(store)
40 grpcHandler.SetSubscriptionManager(subManager) 45 grpcHandler.SetSubscriptionManager(subManager)
41 46
47 connectHandler := connecthandler.NewHandler(grpcHandler)
48
49 mux := http.NewServeMux()
50 path, handler := nostrv1connect.NewNostrRelayHandler(connectHandler, connect.WithInterceptors())
51 mux.Handle(path, handler)
52
42 wsHandler := wshandler.NewHandler(store, subManager) 53 wsHandler := wshandler.NewHandler(store, subManager)
54 mux.Handle("/", wsHandler)
43 55
44 grpcLis, err := net.Listen("tcp", *grpcAddr) 56 grpcLis, err := net.Listen("tcp", *grpcAddr)
45 if err != nil { 57 if err != nil {
@@ -51,11 +63,13 @@ func main() {
51 63
52 httpServer := &http.Server{ 64 httpServer := &http.Server{
53 Addr: *wsAddr, 65 Addr: *wsAddr,
54 Handler: wsHandler, 66 Handler: h2c.NewHandler(mux, &http2.Server{}),
55 } 67 }
56 68
57 log.Printf("gRPC server listening on %s", *grpcAddr) 69 log.Printf("gRPC server listening on %s", *grpcAddr)
58 log.Printf("WebSocket server listening on %s", *wsAddr) 70 log.Printf("HTTP server listening on %s", *wsAddr)
71 log.Printf(" - Connect (gRPC-Web) at %s/nostr.v1.NostrRelay/*", *wsAddr)
72 log.Printf(" - WebSocket (Nostr) at %s/", *wsAddr)
59 log.Printf("Database: %s", *dbPath) 73 log.Printf("Database: %s", *dbPath)
60 74
61 sigChan := make(chan os.Signal, 1) 75 sigChan := make(chan os.Signal, 1)