websocket backend + frontend patching.
This commit is contained in:
@@ -8,10 +8,12 @@ import (
|
||||
"git.aiterp.net/lucifer3/server/services/script"
|
||||
"git.aiterp.net/lucifer3/server/services/uistate"
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -24,6 +26,11 @@ var zeroUUID = uuid.UUID{
|
||||
|
||||
func New(addr string) (lucifer3.Service, error) {
|
||||
svc := &service{}
|
||||
upgrader := websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
|
||||
e := echo.New()
|
||||
e.HideBanner = true
|
||||
@@ -38,6 +45,28 @@ func New(addr string) (lucifer3.Service, error) {
|
||||
return c.JSON(200, data)
|
||||
})
|
||||
|
||||
e.GET("/subscribe", func(c echo.Context) error {
|
||||
ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sub := make(chan uistate.Patch, 64)
|
||||
svc.addSub(sub)
|
||||
|
||||
defer svc.removeSub(sub)
|
||||
defer ws.Close()
|
||||
|
||||
for patch := range sub {
|
||||
err := ws.WriteJSON(patch)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
e.POST("/command", func(c echo.Context) error {
|
||||
var input commandInput
|
||||
err := c.Bind(&input)
|
||||
@@ -115,6 +144,7 @@ type service struct {
|
||||
mu sync.Mutex
|
||||
data uistate.Data
|
||||
bus *lucifer3.EventBus
|
||||
subs []chan uistate.Patch
|
||||
}
|
||||
|
||||
func (s *service) Active() bool {
|
||||
@@ -130,12 +160,36 @@ func (s *service) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) {
|
||||
case uistate.Patch:
|
||||
s.mu.Lock()
|
||||
s.data = s.data.WithPatch(event)
|
||||
subs := s.subs
|
||||
s.mu.Unlock()
|
||||
|
||||
// TODO: Broadcast websockets
|
||||
for _, sub := range subs {
|
||||
select {
|
||||
case sub <- event:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) addSub(ch chan uistate.Patch) {
|
||||
s.mu.Lock()
|
||||
s.subs = append(s.subs, ch)
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (s *service) removeSub(ch chan uistate.Patch) {
|
||||
s.mu.Lock()
|
||||
s.subs = append([]chan uistate.Patch{}, s.subs...)
|
||||
for i, sub := range s.subs {
|
||||
if sub == ch {
|
||||
s.subs = append(s.subs[:i], s.subs[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
type commandInput struct {
|
||||
Assign *assignInput `json:"assign,omitempty"`
|
||||
AddAlias *commands.AddAlias `json:"addAlias,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user