Initial project snapshot

This commit is contained in:
2026-04-28 22:29:50 +03:00
commit 8ba0561f4f
365 changed files with 91832 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
package main
import (
"context"
"log"
"os/signal"
"syscall"
"github.com/example/remote-access-platform/backend/internal/platform/runtime"
)
func main() {
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
app, err := runtime.NewApp(ctx)
if err != nil {
log.Fatalf("bootstrap app: %v", err)
}
if err := app.Run(ctx); err != nil {
log.Fatalf("run app: %v", err)
}
}
+94
View File
@@ -0,0 +1,94 @@
package main
import (
"context"
"flag"
"fmt"
"log"
"net/url"
"os"
"os/signal"
"strings"
"time"
"github.com/gorilla/websocket"
)
func main() {
var (
gatewayURL = flag.String("gateway-url", "ws://127.0.0.1:8080/api/v1/gateway/ws", "websocket gateway url")
attachToken = flag.String("attach-token", "", "short-lived attach token")
duration = flag.Duration("duration", 90*time.Second, "maximum time to keep the client attached")
heartbeatInterval = flag.Duration("heartbeat-interval", 10*time.Second, "client heartbeat interval")
exitOnTakenOver = flag.Bool("exit-on-taken-over", true, "exit successfully after receiving session.taken_over")
)
flag.Parse()
if *attachToken == "" {
log.Fatal("attach-token is required")
}
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
if *duration > 0 {
var timeoutCancel context.CancelFunc
ctx, timeoutCancel = context.WithTimeout(ctx, *duration)
defer timeoutCancel()
}
targetURL, err := url.Parse(*gatewayURL)
if err != nil {
log.Fatalf("parse gateway url: %v", err)
}
query := targetURL.Query()
query.Set("attach_token", *attachToken)
targetURL.RawQuery = query.Encode()
conn, _, err := websocket.DefaultDialer.DialContext(ctx, targetURL.String(), nil)
if err != nil {
log.Fatalf("dial websocket: %v", err)
}
defer conn.Close()
done := make(chan error, 1)
go func() {
for {
_, payload, err := conn.ReadMessage()
if err != nil {
done <- err
return
}
fmt.Println(string(payload))
if *exitOnTakenOver && containsTakenOver(payload) {
done <- nil
return
}
}
}()
heartbeatTicker := time.NewTicker(*heartbeatInterval)
defer heartbeatTicker.Stop()
for {
select {
case err := <-done:
if err != nil {
log.Fatalf("websocket read: %v", err)
}
return
case <-heartbeatTicker.C:
if err := conn.WriteJSON(map[string]any{"type": "heartbeat"}); err != nil {
log.Fatalf("heartbeat write: %v", err)
}
case <-ctx.Done():
if err := ctx.Err(); err != nil && err != context.Canceled && err != context.DeadlineExceeded {
log.Fatalf("context ended: %v", err)
}
return
}
}
}
func containsTakenOver(payload []byte) bool {
return strings.Contains(string(payload), `"type":"session.taken_over"`)
}