Feature(Go): Web auth, WebSocket signaling and live device list (Phase 3)
This commit is contained in:
@@ -2,6 +2,7 @@ package web
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -9,21 +10,28 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/yuanyuanxiang/SimpleRemoter/server/go/hub"
|
||||
"github.com/yuanyuanxiang/SimpleRemoter/server/go/logger"
|
||||
"github.com/yuanyuanxiang/SimpleRemoter/server/go/wsauth"
|
||||
)
|
||||
|
||||
// Server serves the web remote desktop UI: the embedded index.html, xterm.js
|
||||
// static assets, and the PWA manifest. WebSocket signaling, device list and
|
||||
// screen streaming will be wired up in later phases.
|
||||
// static assets, the PWA manifest, and JSON APIs backed by the device hub.
|
||||
// WebSocket signaling and screen streaming will be wired up in later phases.
|
||||
type Server struct {
|
||||
port int
|
||||
log *logger.Logger
|
||||
srv *http.Server
|
||||
hub *hub.Hub
|
||||
auth *wsauth.Authenticator
|
||||
ws *wsHub
|
||||
}
|
||||
|
||||
// New creates an HTTP server bound to the given port. port=0 disables the server.
|
||||
func New(port int, log *logger.Logger) *Server {
|
||||
return &Server{port: port, log: log}
|
||||
// The hub provides read access to the online-device registry; the authenticator
|
||||
// owns user accounts and session tokens.
|
||||
func New(port int, log *logger.Logger, h *hub.Hub, auth *wsauth.Authenticator) *Server {
|
||||
return &Server{port: port, log: log, hub: h, auth: auth}
|
||||
}
|
||||
|
||||
// Start launches the server in a goroutine and returns immediately.
|
||||
@@ -34,10 +42,14 @@ func (s *Server) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
s.ws = newWSHub(s.auth, s.hub, s.log)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", s.handleIndex)
|
||||
mux.HandleFunc("/health", s.handleHealth)
|
||||
mux.HandleFunc("/manifest.json", s.handleManifest)
|
||||
mux.HandleFunc("/api/devices", s.handleDevices)
|
||||
mux.HandleFunc("/ws", s.ws.serve)
|
||||
mux.HandleFunc("/static/xterm.js", staticHandler(xtermJS, "application/javascript; charset=utf-8"))
|
||||
mux.HandleFunc("/static/xterm.css", staticHandler(xtermCSS, "text/css; charset=utf-8"))
|
||||
mux.HandleFunc("/static/xterm-fit.js", staticHandler(xtermFitJS, "application/javascript; charset=utf-8"))
|
||||
@@ -66,6 +78,9 @@ func (s *Server) Start() error {
|
||||
|
||||
// Stop gracefully shuts the server down.
|
||||
func (s *Server) Stop() {
|
||||
if s.ws != nil {
|
||||
s.ws.stop()
|
||||
}
|
||||
if s.srv == nil {
|
||||
return
|
||||
}
|
||||
@@ -89,6 +104,18 @@ func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = w.Write([]byte(`{"status":"ok"}`))
|
||||
}
|
||||
|
||||
// handleDevices returns a JSON snapshot of currently-online devices. Empty
|
||||
// array (not null) when no clients are connected — matches what the front-end
|
||||
// will eventually expect.
|
||||
func (s *Server) handleDevices(w http.ResponseWriter, r *http.Request) {
|
||||
devices := s.hub.ListDevices()
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
if err := json.NewEncoder(w).Encode(devices); err != nil {
|
||||
s.log.Error("encode /api/devices: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// PWA manifest. Referenced by <link rel="manifest"> in index.html.
|
||||
// Static JSON, no template needed.
|
||||
const manifestJSON = `{
|
||||
|
||||
Reference in New Issue
Block a user