mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 06:23:00 +00:00
feat: update WebRTC handlers to support dynamic SFU host configuration and add monitoring script
This commit is contained in:
parent
3597c61cfc
commit
bcfdabb32d
158
example.http
158
example.http
@ -1,158 +0,0 @@
|
||||
### Orama Network Gateway API Examples
|
||||
# This file is designed for the VS Code "REST Client" extension.
|
||||
# It demonstrates the core capabilities of the DeBros Network Gateway.
|
||||
|
||||
@baseUrl = http://localhost:6001
|
||||
@apiKey = ak_X32jj2fiin8zzv0hmBKTC5b5:default
|
||||
@contentType = application/json
|
||||
|
||||
############################################################
|
||||
### 1. SYSTEM & HEALTH
|
||||
############################################################
|
||||
|
||||
# @name HealthCheck
|
||||
GET {{baseUrl}}/v1/health
|
||||
X-API-Key: {{apiKey}}
|
||||
|
||||
###
|
||||
|
||||
# @name SystemStatus
|
||||
# Returns the full status of the gateway and connected services
|
||||
GET {{baseUrl}}/v1/status
|
||||
X-API-Key: {{apiKey}}
|
||||
|
||||
###
|
||||
|
||||
# @name NetworkStatus
|
||||
# Returns the P2P network status and PeerID
|
||||
GET {{baseUrl}}/v1/network/status
|
||||
X-API-Key: {{apiKey}}
|
||||
|
||||
|
||||
############################################################
|
||||
### 2. DISTRIBUTED CACHE (OLRIC)
|
||||
############################################################
|
||||
|
||||
# @name CachePut
|
||||
# Stores a value in the distributed cache (DMap)
|
||||
POST {{baseUrl}}/v1/cache/put
|
||||
X-API-Key: {{apiKey}}
|
||||
Content-Type: {{contentType}}
|
||||
|
||||
{
|
||||
"dmap": "demo-cache",
|
||||
"key": "video-demo",
|
||||
"value": "Hello from REST Client!"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
# @name CacheGet
|
||||
# Retrieves a value from the distributed cache
|
||||
POST {{baseUrl}}/v1/cache/get
|
||||
X-API-Key: {{apiKey}}
|
||||
Content-Type: {{contentType}}
|
||||
|
||||
{
|
||||
"dmap": "demo-cache",
|
||||
"key": "video-demo"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
# @name CacheScan
|
||||
# Scans for keys in a specific DMap
|
||||
POST {{baseUrl}}/v1/cache/scan
|
||||
X-API-Key: {{apiKey}}
|
||||
Content-Type: {{contentType}}
|
||||
|
||||
{
|
||||
"dmap": "demo-cache"
|
||||
}
|
||||
|
||||
|
||||
############################################################
|
||||
### 3. DECENTRALIZED STORAGE (IPFS)
|
||||
############################################################
|
||||
|
||||
# @name StorageUpload
|
||||
# Uploads a file to IPFS (Multipart)
|
||||
POST {{baseUrl}}/v1/storage/upload
|
||||
X-API-Key: {{apiKey}}
|
||||
Content-Type: multipart/form-data; boundary=boundary
|
||||
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="file"; filename="demo.txt"
|
||||
Content-Type: text/plain
|
||||
|
||||
This is a demonstration of decentralized storage on the Sonr Network.
|
||||
--boundary--
|
||||
|
||||
###
|
||||
|
||||
# @name StorageStatus
|
||||
# Check the pinning status and replication of a CID
|
||||
# Replace {cid} with the CID returned from the upload above
|
||||
@demoCid = bafkreid76y6x6v2n5o4n6n5o4n6n5o4n6n5o4n6n5o4
|
||||
GET {{baseUrl}}/v1/storage/status/{{demoCid}}
|
||||
X-API-Key: {{apiKey}}
|
||||
|
||||
###
|
||||
|
||||
# @name StorageDownload
|
||||
# Retrieve content directly from IPFS via the gateway
|
||||
GET {{baseUrl}}/v1/storage/get/{{demoCid}}
|
||||
X-API-Key: {{apiKey}}
|
||||
|
||||
|
||||
############################################################
|
||||
### 4. REAL-TIME PUB/SUB
|
||||
############################################################
|
||||
|
||||
# @name ListTopics
|
||||
# Lists all active topics in the current namespace
|
||||
GET {{baseUrl}}/v1/pubsub/topics
|
||||
X-API-Key: {{apiKey}}
|
||||
|
||||
###
|
||||
|
||||
# @name PublishMessage
|
||||
# Publishes a base64 encoded message to a topic
|
||||
POST {{baseUrl}}/v1/pubsub/publish
|
||||
X-API-Key: {{apiKey}}
|
||||
Content-Type: {{contentType}}
|
||||
|
||||
{
|
||||
"topic": "network-updates",
|
||||
"data_base64": "U29uciBOZXR3b3JrIGlzIGF3ZXNvbWUh"
|
||||
}
|
||||
|
||||
|
||||
############################################################
|
||||
### 5. SERVERLESS FUNCTIONS
|
||||
############################################################
|
||||
|
||||
# @name ListFunctions
|
||||
# Lists all deployed serverless functions
|
||||
GET {{baseUrl}}/v1/functions
|
||||
X-API-Key: {{apiKey}}
|
||||
|
||||
###
|
||||
|
||||
# @name InvokeFunction
|
||||
# Invokes a deployed function by name
|
||||
# Path: /v1/invoke/{namespace}/{functionName}
|
||||
POST {{baseUrl}}/v1/invoke/default/hello
|
||||
X-API-Key: {{apiKey}}
|
||||
Content-Type: {{contentType}}
|
||||
|
||||
{
|
||||
"name": "Developer"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
# @name WhoAmI
|
||||
# Validates the API Key and returns caller identity
|
||||
GET {{baseUrl}}/v1/auth/whoami
|
||||
X-API-Key: {{apiKey}}
|
||||
@ -340,6 +340,7 @@ func New(logger *logging.ColoredLogger, cfg *Config) (*Gateway, error) {
|
||||
if cfg.WebRTCEnabled && cfg.SFUPort > 0 {
|
||||
gw.webrtcHandlers = webrtchandlers.NewWebRTCHandlers(
|
||||
logger,
|
||||
gw.localWireGuardIP,
|
||||
cfg.SFUPort,
|
||||
cfg.TURNDomain,
|
||||
cfg.TURNSecret,
|
||||
|
||||
@ -15,6 +15,7 @@ func testHandlers() *WebRTCHandlers {
|
||||
logger, _ := logging.NewColoredLogger(logging.ComponentGeneral, false)
|
||||
return NewWebRTCHandlers(
|
||||
logger,
|
||||
"", // defaults to 127.0.0.1 in tests
|
||||
8443,
|
||||
"turn.ns-test.dbrs.space",
|
||||
"test-secret-key-32bytes-long!!!!",
|
||||
@ -91,7 +92,7 @@ func TestCredentialsHandler_NoNamespace(t *testing.T) {
|
||||
|
||||
func TestCredentialsHandler_NoTURNSecret(t *testing.T) {
|
||||
logger, _ := logging.NewColoredLogger(logging.ComponentGeneral, false)
|
||||
h := NewWebRTCHandlers(logger, 8443, "turn.test.dbrs.space", "", nil)
|
||||
h := NewWebRTCHandlers(logger, "", 8443, "turn.test.dbrs.space", "", nil)
|
||||
|
||||
req := requestWithNamespace("POST", "/v1/webrtc/turn/credentials", "test-ns")
|
||||
w := httptest.NewRecorder()
|
||||
@ -119,7 +120,7 @@ func TestSignalHandler_NoNamespace(t *testing.T) {
|
||||
|
||||
func TestSignalHandler_NoSFUPort(t *testing.T) {
|
||||
logger, _ := logging.NewColoredLogger(logging.ComponentGeneral, false)
|
||||
h := NewWebRTCHandlers(logger, 0, "", "secret", nil)
|
||||
h := NewWebRTCHandlers(logger, "", 0, "", "secret", nil)
|
||||
|
||||
req := requestWithNamespace("GET", "/v1/webrtc/signal", "test-ns")
|
||||
w := httptest.NewRecorder()
|
||||
@ -171,7 +172,7 @@ func TestRoomsHandler_NoNamespace(t *testing.T) {
|
||||
|
||||
func TestRoomsHandler_NoSFUPort(t *testing.T) {
|
||||
logger, _ := logging.NewColoredLogger(logging.ComponentGeneral, false)
|
||||
h := NewWebRTCHandlers(logger, 0, "", "secret", nil)
|
||||
h := NewWebRTCHandlers(logger, "", 0, "", "secret", nil)
|
||||
|
||||
req := requestWithNamespace("GET", "/v1/webrtc/rooms", "test-ns")
|
||||
w := httptest.NewRecorder()
|
||||
@ -206,7 +207,7 @@ func TestRoomsHandler_SFUProxySuccess(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
h := NewWebRTCHandlers(logger, port, "", "secret", nil)
|
||||
h := NewWebRTCHandlers(logger, "", port, "", "secret", nil)
|
||||
req := requestWithNamespace("GET", "/v1/webrtc/rooms", "test-ns")
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ func (h *WebRTCHandlers) RoomsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Proxy to SFU health endpoint which returns room count
|
||||
targetURL := fmt.Sprintf("http://127.0.0.1:%d/health", h.sfuPort)
|
||||
targetURL := fmt.Sprintf("http://%s:%d/health", h.sfuHost, h.sfuPort)
|
||||
|
||||
client := &http.Client{Timeout: 5 * time.Second}
|
||||
resp, err := client.Get(targetURL)
|
||||
|
||||
@ -23,8 +23,7 @@ func (h *WebRTCHandlers) SignalHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Proxy WebSocket to local SFU on WireGuard IP
|
||||
// SFU binds to WireGuard IP, so we use 127.0.0.1 since we're on the same node
|
||||
targetHost := fmt.Sprintf("127.0.0.1:%d", h.sfuPort)
|
||||
targetHost := fmt.Sprintf("%s:%d", h.sfuHost, h.sfuPort)
|
||||
|
||||
h.logger.ComponentDebug(logging.ComponentGeneral, "Proxying WebRTC signal to SFU",
|
||||
zap.String("namespace", ns),
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
// These run on the namespace gateway and proxy signaling to the local SFU.
|
||||
type WebRTCHandlers struct {
|
||||
logger *logging.ColoredLogger
|
||||
sfuHost string // SFU host IP (WireGuard IP) to proxy connections to
|
||||
sfuPort int // Local SFU signaling port to proxy WebSocket connections to
|
||||
turnDomain string // TURN server domain for building URIs
|
||||
turnSecret string // HMAC-SHA1 shared secret for TURN credential generation
|
||||
@ -23,13 +24,18 @@ type WebRTCHandlers struct {
|
||||
// NewWebRTCHandlers creates a new WebRTCHandlers instance.
|
||||
func NewWebRTCHandlers(
|
||||
logger *logging.ColoredLogger,
|
||||
sfuHost string,
|
||||
sfuPort int,
|
||||
turnDomain string,
|
||||
turnSecret string,
|
||||
proxyWS func(w http.ResponseWriter, r *http.Request, targetHost string) bool,
|
||||
) *WebRTCHandlers {
|
||||
if sfuHost == "" {
|
||||
sfuHost = "127.0.0.1"
|
||||
}
|
||||
return &WebRTCHandlers{
|
||||
logger: logger,
|
||||
sfuHost: sfuHost,
|
||||
sfuPort: sfuPort,
|
||||
turnDomain: turnDomain,
|
||||
turnSecret: turnSecret,
|
||||
|
||||
36
scripts/monitor-webrtc.sh
Executable file
36
scripts/monitor-webrtc.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
# Monitor WebRTC endpoints every 10 seconds
|
||||
# Usage: ./scripts/monitor-webrtc.sh
|
||||
|
||||
API_KEY="ak_SiODBDJFHrfE3HxjOtSe4CYm:anchat-test"
|
||||
BASE="https://ns-anchat-test.orama-devnet.network"
|
||||
|
||||
while true; do
|
||||
TS=$(date '+%H:%M:%S')
|
||||
|
||||
# 1. Health check
|
||||
HEALTH=$(curl -sk -o /dev/null -w "%{http_code}" "${BASE}/v1/health")
|
||||
|
||||
# 2. TURN credentials
|
||||
CREDS=$(curl -sk -o /dev/null -w "%{http_code}" -X POST -H "X-API-Key: ${API_KEY}" "${BASE}/v1/webrtc/turn/credentials")
|
||||
|
||||
# 3. WebSocket signal (connect, send join, read response, disconnect)
|
||||
WS_OUT=$(echo '{"type":"join","data":{"roomId":"monitor-room","userId":"monitor"}}' \
|
||||
| timeout 5 websocat -k --no-close -t "wss://ns-anchat-test.orama-devnet.network/v1/webrtc/signal?token=${API_KEY}" 2>&1 \
|
||||
| head -1)
|
||||
|
||||
if echo "$WS_OUT" | grep -q '"welcome"'; then
|
||||
SIGNAL="OK"
|
||||
else
|
||||
SIGNAL="FAIL"
|
||||
fi
|
||||
|
||||
# Print status
|
||||
if [ "$HEALTH" = "200" ] && [ "$CREDS" = "200" ] && [ "$SIGNAL" = "OK" ]; then
|
||||
echo "$TS health=$HEALTH creds=$CREDS signal=$SIGNAL ✓"
|
||||
else
|
||||
echo "$TS health=$HEALTH creds=$CREDS signal=$SIGNAL ✗ PROBLEM"
|
||||
fi
|
||||
|
||||
sleep 10
|
||||
done
|
||||
Loading…
x
Reference in New Issue
Block a user