Added many Eventbus Structs for the Frontend Handling
This commit is contained in:
+109
-36
@@ -3,6 +3,7 @@ package frontend
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -33,16 +34,15 @@ func New(bus eventbus.EventBus) *FServer {
|
||||
}
|
||||
|
||||
func (fsrv *FServer) routes() {
|
||||
// Statische Dateien aus dem Embed-FS
|
||||
// "www" Präfix entfernen, damit index.html unter / verfügbar ist
|
||||
// Static files from the Embed-FS
|
||||
// remove "www" prefix, so index.html is reachable over /
|
||||
root, _ := fs.Sub(staticFiles, "www")
|
||||
fsrv.mux.Handle("/", http.FileServer(http.FS(root)))
|
||||
|
||||
// WebSocket Endpunkt
|
||||
fsrv.mux.HandleFunc("/ws", fsrv.handleWS)
|
||||
}
|
||||
|
||||
func (fsrv *FServer) handleWS(w http.ResponseWriter, r *http.Request) {
|
||||
func (fs *FServer) handleWS(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Printf("Upgrade error: %v", err)
|
||||
@@ -50,53 +50,126 @@ func (fsrv *FServer) handleWS(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Kanäle für die Hardware-Events abonnieren
|
||||
rxChan := fsrv.bus.Subscribe(api.TopicUARTRx)
|
||||
txChan := fsrv.bus.Subscribe(api.TopicUARTTx)
|
||||
|
||||
// Context nutzen, um Goroutinen zu stoppen, wenn die Verbindung abreißt
|
||||
ctx, cancel := context.WithCancel(r.Context())
|
||||
defer cancel()
|
||||
|
||||
// WRITER: Send Events to Browser
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case f := <-rxChan:
|
||||
if err := conn.WriteJSON(map[string]any{"type": "rx", "frame": f}); err != nil {
|
||||
return
|
||||
}
|
||||
case f := <-txChan:
|
||||
if err := conn.WriteJSON(map[string]any{"type": "tx", "frame": f}); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
go fs.HandleAppEvents(ctx, conn)
|
||||
|
||||
// READER: Commands from Browser
|
||||
for {
|
||||
var cmd api.WsMessage
|
||||
if err := conn.ReadJSON(&cmd); err != nil {
|
||||
log.Printf("WS Read Error: %v", err)
|
||||
break
|
||||
}
|
||||
|
||||
fsrv.bus.Publish(api.TopicFrontendCmd, cmd)
|
||||
log.Printf("Browser Action: %s auf with %v", cmd.Cmd, cmd.Payload)
|
||||
}
|
||||
// This Function is Blocking
|
||||
fs.GetFrontendEvents(ctx, conn)
|
||||
}
|
||||
|
||||
func (fsrv *FServer) Start(addr string) error {
|
||||
func (fs *FServer) Start(addr string) error {
|
||||
server := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: fsrv.mux,
|
||||
Handler: fs.mux,
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
ctx, cancle := context.WithCancel(context.Background())
|
||||
defer cancle()
|
||||
|
||||
go fs.HandleFrontendEvents(ctx)
|
||||
|
||||
log.Printf("Frontend Server gestartet auf %s", addr)
|
||||
return server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (fs *FServer) HandleAppEvents(ctx context.Context, conn *websocket.Conn) error {
|
||||
// Kanäle für die Hardware-Events abonnieren
|
||||
rxChan := fs.bus.Subscribe(api.TopicUARTRx)
|
||||
txChan := fs.bus.Subscribe(api.TopicUARTTx)
|
||||
UartActions := fs.bus.Subscribe(api.TopicUartAction)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case f := <-rxChan:
|
||||
if err := conn.WriteJSON(map[string]any{"type": "rx", "frame": f}); err != nil {
|
||||
return nil
|
||||
}
|
||||
case f := <-txChan:
|
||||
if err := conn.WriteJSON(map[string]any{"type": "tx", "frame": f}); err != nil {
|
||||
return nil
|
||||
}
|
||||
case msgT := <-UartActions:
|
||||
switch msg := msgT.(type) {
|
||||
case api.ActionUartConnected:
|
||||
// TODO: nicht hier die daten nachhaltig speichern damit sie ans frontend gesendet werden können
|
||||
// TODO: das muss irgendwo central passieren nicht für jeden client
|
||||
if msg.Error != nil {
|
||||
}
|
||||
continue
|
||||
case api.ActionUartDisconnected:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *FServer) GetFrontendEvents(ctx context.Context, conn *websocket.Conn) error {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
default:
|
||||
var cmd api.WsMessage
|
||||
if err := conn.ReadJSON(&cmd); err != nil {
|
||||
log.Printf("WS Read Error: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
val, ok := api.MessageReceiveRegistry[cmd.Cmd]
|
||||
if !ok {
|
||||
log.Printf("No Message Type mapped to %v", cmd.Cmd)
|
||||
continue
|
||||
}
|
||||
valM := val()
|
||||
|
||||
err := json.Unmarshal(cmd.Payload, valM)
|
||||
if err != nil {
|
||||
log.Printf("Could not Unmarshal payload %v", cmd.Payload)
|
||||
}
|
||||
|
||||
fs.bus.Publish(api.TopicFrontendCmd, valM)
|
||||
log.Printf("Browser Action: %s auf with %v", cmd.Cmd, cmd.Payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *FServer) HandleFrontendEvents(ctx context.Context) error {
|
||||
fChan := fs.bus.Subscribe(api.TopicFrontendCmd)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case msg := <-fChan:
|
||||
switch msgT := msg.(type) {
|
||||
case api.WsUartSendMessage:
|
||||
log.Printf("Sending Uart Data % X", msgT.Data)
|
||||
fs.bus.Publish(api.TopicUartAction, api.ActionUartSendMessage{
|
||||
MsgId: msgT.MsgId,
|
||||
Data: msgT.Data,
|
||||
})
|
||||
continue
|
||||
case api.WsUartConnect:
|
||||
log.Printf("Connect with %s : %d", msgT.SelectedAdapter, msgT.Baudrate)
|
||||
fs.bus.Publish(api.TopicUartAction, api.ActionUartConnect{
|
||||
Adapter: msgT.SelectedAdapter,
|
||||
Baudrate: msgT.Baudrate,
|
||||
})
|
||||
continue
|
||||
case api.WsUartDisconnect:
|
||||
log.Printf("Disconnect from Uart Adapter")
|
||||
fs.bus.Publish(api.TopicUartAction, api.ActionUartDisconnect{})
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user