-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathview_server.go
149 lines (131 loc) · 3.89 KB
/
view_server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package gostream
import (
"context"
"embed"
"errors"
"fmt"
"image"
"io"
"io/fs"
"net/http"
"os"
"strings"
"sync"
"time"
"github.com/edaniels/golog"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/trevor403/gostream/pkg/input/direct"
"github.com/trevor403/gostream/pkg/platform"
)
// A ViewServer is a convenience helper for solely streaming a series
// Views. Views can be added over time for future new connections.
type ViewServer interface {
// Start starts the server and waits for new connections.
Start() error
// Stop stops the server and stops the underlying views.
Stop(ctx context.Context) error
}
type viewServer struct {
port int
views []View
httpServer *http.Server
started bool
logger golog.Logger
backgroundProcessing sync.WaitGroup
}
// NewViewServer returns a server that will run on the given port and initially starts
// with the given view.
func NewViewServer(port int, view View, logger golog.Logger) ViewServer {
return &viewServer{port: port, views: []View{view}, logger: logger}
}
// ErrServerAlreadyStarted happens when the server has already been started.
var ErrServerAlreadyStarted = errors.New("already started")
func (rvs *viewServer) Start() error {
if rvs.started {
return ErrServerAlreadyStarted
}
rvs.started = true
httpServer := &http.Server{
Addr: fmt.Sprintf(":%d", rvs.port),
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
rvs.httpServer = httpServer
mux := mux.NewRouter()
// http.NewServeMux()
httpServer.Handler = mux
staticDirectory := "assets/static"
staticPaths := map[string]embed.FS{
"core": coreFS,
}
for pathName, pathFS := range staticPaths {
pathPrefix := "/" + pathName + "/"
fs, err := fs.Sub(pathFS, staticDirectory)
fmt.Println(err)
srv := http.FileServer(http.FS(fs))
mux.PathPrefix(pathPrefix).Handler(srv)
}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path[1:]
if path == "" {
path = "index.html"
}
s := strings.NewReader(mainHTML)
http.ServeContent(w, r, "index.html", time.Now(), s)
})
mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) {
bv := rvs.views[0]
servers := bv.SinglePageHTML()
io.WriteString(w, servers)
})
for _, view := range rvs.views {
handler := view.Handler()
fmt.Println("handler.Name", handler.Name)
mux.Handle("/"+handler.Name, handler.Func)
}
handle := platform.NewCursorHandle()
handle.SetCallback(func(img image.Image, width int, height int, hotx int, hoty int) {
for _, view := range rvs.views {
view.SendCursorToAll(img, width, height, hotx, hoty)
}
fmt.Println("detected new cursor", len(img.(*image.RGBA).Pix))
})
handle.Start()
for _, view := range rvs.views {
view.SetOnSizeHandler(func(ctx context.Context, factor float32, responder ClientResponder) {
if factor > 5 {
factor = 1
}
Logger.Debugw("scaled", "factor", factor)
handle.UpdateScale(factor)
})
view.SetOnDataHandler(func(ctx context.Context, data []byte, responder ClientResponder) {
direct.Handle(data)
})
}
mux.Use(func(next http.Handler) http.Handler { return handlers.LoggingHandler(os.Stdout, next) })
rvs.backgroundProcessing.Add(1)
go func() {
defer rvs.backgroundProcessing.Done()
addr, err := LocalIP()
if err != nil {
rvs.logger.Errorw("error getting local ip", "error", err)
return
}
rvs.logger.Infow("listening", "url", fmt.Sprintf("http://%v:%d", addr, rvs.port), "port", rvs.port)
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
rvs.logger.Errorw("error listening and serving", "error", err)
}
}()
return nil
}
func (rvs *viewServer) Stop(ctx context.Context) error {
for _, view := range rvs.views {
view.Stop()
}
err := rvs.httpServer.Shutdown(ctx)
rvs.backgroundProcessing.Wait()
return err
}