Websocket working again
This commit is contained in:
parent
74cd44c66d
commit
c85dab3573
13 changed files with 166 additions and 26 deletions
1
go.mod
1
go.mod
|
@ -6,6 +6,7 @@ require (
|
||||||
github.com/caarlos0/env/v6 v6.10.1
|
github.com/caarlos0/env/v6 v6.10.1
|
||||||
github.com/dariubs/percent v1.0.0
|
github.com/dariubs/percent v1.0.0
|
||||||
github.com/fsnotify/fsnotify v1.6.0
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/labstack/echo/v4 v4.9.1
|
github.com/labstack/echo/v4 v4.9.1
|
||||||
github.com/shirou/gopsutil/v3 v3.22.11
|
github.com/shirou/gopsutil/v3 v3.22.11
|
||||||
github.com/unjx-de/go-folder v1.0.7
|
github.com/unjx-de/go-folder v1.0.7
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -16,6 +16,8 @@ github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzq
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
|
github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
|
||||||
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
|
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
|
||||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||||
|
|
62
hub/hub.go
Normal file
62
hub/hub.go
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
package hub
|
||||||
|
|
||||||
|
const (
|
||||||
|
Weather WsType = iota
|
||||||
|
System
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
NotifierChan chan Message
|
||||||
|
|
||||||
|
WsType uint
|
||||||
|
Message struct {
|
||||||
|
WsType WsType `json:"ws_type"`
|
||||||
|
Message interface{} `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Hub struct {
|
||||||
|
Notifier NotifierChan
|
||||||
|
NewClients chan NotifierChan
|
||||||
|
ClosingClients chan NotifierChan
|
||||||
|
clients map[NotifierChan]struct{}
|
||||||
|
LiveInformationCh chan Message
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewHub() *Hub {
|
||||||
|
hub := Hub{}
|
||||||
|
hub.LiveInformationCh = make(chan Message)
|
||||||
|
hub.Notifier = make(NotifierChan)
|
||||||
|
hub.NewClients = make(chan NotifierChan)
|
||||||
|
hub.ClosingClients = make(chan NotifierChan)
|
||||||
|
hub.clients = make(map[NotifierChan]struct{})
|
||||||
|
go hub.listen()
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
if msg, ok := <-hub.LiveInformationCh; ok {
|
||||||
|
hub.Notifier <- msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return &hub
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Hub) listen() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case s := <-h.NewClients:
|
||||||
|
h.clients[s] = struct{}{}
|
||||||
|
case s := <-h.ClosingClients:
|
||||||
|
delete(h.clients, s)
|
||||||
|
case event := <-h.Notifier:
|
||||||
|
for client := range h.clients {
|
||||||
|
select {
|
||||||
|
case client <- event:
|
||||||
|
default:
|
||||||
|
close(client)
|
||||||
|
delete(h.clients, client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
main.go
11
main.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"godash/bookmarks"
|
"godash/bookmarks"
|
||||||
|
"godash/hub"
|
||||||
"godash/system"
|
"godash/system"
|
||||||
"godash/weather"
|
"godash/weather"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
@ -17,6 +18,7 @@ import (
|
||||||
type goDash struct {
|
type goDash struct {
|
||||||
router *echo.Echo
|
router *echo.Echo
|
||||||
logger *zap.SugaredLogger
|
logger *zap.SugaredLogger
|
||||||
|
hub *hub.Hub
|
||||||
config config
|
config config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +31,7 @@ type config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
g := goDash{router: echo.New()}
|
g := goDash{router: echo.New(), hub: hub.NewHub()}
|
||||||
g.router.Renderer = &TemplateRenderer{
|
g.router.Renderer = &TemplateRenderer{
|
||||||
templates: template.Must(template.ParseGlob("templates/*.gohtml")),
|
templates: template.Must(template.ParseGlob("templates/*.gohtml")),
|
||||||
}
|
}
|
||||||
|
@ -45,11 +47,11 @@ func main() {
|
||||||
g.router.Use(middleware.GzipWithConfig(middleware.GzipConfig{Level: 5}))
|
g.router.Use(middleware.GzipWithConfig(middleware.GzipConfig{Level: 5}))
|
||||||
g.router.Pre(middleware.RemoveTrailingSlash())
|
g.router.Pre(middleware.RemoveTrailingSlash())
|
||||||
|
|
||||||
w := weather.NewWeatherService(g.logger)
|
w := weather.NewWeatherService(g.logger, g.hub)
|
||||||
b := bookmarks.NewBookmarkService(g.logger)
|
b := bookmarks.NewBookmarkService(g.logger)
|
||||||
var s *system.System
|
var s *system.System
|
||||||
if g.config.LiveSystem {
|
if g.config.LiveSystem {
|
||||||
s = system.NewSystemService(g.logger)
|
s = system.NewSystemService(g.logger, g.hub)
|
||||||
}
|
}
|
||||||
|
|
||||||
g.router.GET("/", func(c echo.Context) error {
|
g.router.GET("/", func(c echo.Context) error {
|
||||||
|
@ -57,9 +59,10 @@ func main() {
|
||||||
"Title": g.config.Title,
|
"Title": g.config.Title,
|
||||||
"Weather": w.CurrentWeather,
|
"Weather": w.CurrentWeather,
|
||||||
"Bookmarks": b.Categories,
|
"Bookmarks": b.Categories,
|
||||||
"System": s,
|
"System": s.CurrentSystem,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
g.router.GET("/ws", g.ws)
|
||||||
g.router.Static("/static", "static")
|
g.router.Static("/static", "static")
|
||||||
g.router.Static("/storage/icons", "storage/icons")
|
g.router.Static("/storage/icons", "storage/icons")
|
||||||
|
|
||||||
|
|
56
routes.go
Normal file
56
routes.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"godash/hub"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
upgrader = websocket.Upgrader{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (g *goDash) ws(c echo.Context) error {
|
||||||
|
if g.config.PageUrl.String() != c.Request().Header.Get("Origin") {
|
||||||
|
return errors.New("bad request")
|
||||||
|
}
|
||||||
|
ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
messageChan := make(hub.NotifierChan)
|
||||||
|
g.hub.NewClients <- messageChan
|
||||||
|
defer func() {
|
||||||
|
g.hub.ClosingClients <- messageChan
|
||||||
|
ws.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer ws.Close()
|
||||||
|
for {
|
||||||
|
_, _, err := ws.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case msg, ok := <-messageChan:
|
||||||
|
if !ok {
|
||||||
|
err := ws.WriteMessage(websocket.CloseMessage, []byte{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err := ws.WriteJSON(msg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -24,5 +24,5 @@ func (s *System) liveCpu() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.Live.CPU = math.RoundToEven(p[0])
|
s.CurrentSystem.Live.CPU = math.RoundToEven(p[0])
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,6 @@ func (s *System) liveDisk() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.Live.Disk.Value = readableSize(d.Used)
|
s.CurrentSystem.Live.Disk.Value = readableSize(d.Used)
|
||||||
s.Live.Disk.Percentage = math.RoundToEven(percent.PercentOfFloat(float64(d.Used), float64(d.Total)))
|
s.CurrentSystem.Live.Disk.Percentage = math.RoundToEven(percent.PercentOfFloat(float64(d.Used), float64(d.Total)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,6 @@ func (s *System) liveRam() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.Live.Ram.Value = readableSize(r.Used)
|
s.CurrentSystem.Live.Ram.Value = readableSize(r.Used)
|
||||||
s.Live.Ram.Percentage = math.RoundToEven(percent.PercentOfFloat(float64(r.Used), float64(r.Total)))
|
s.CurrentSystem.Live.Ram.Percentage = math.RoundToEven(percent.PercentOfFloat(float64(r.Used), float64(r.Total)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,12 @@ package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"godash/hub"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSystemService(logging *zap.SugaredLogger) *System {
|
func NewSystemService(logging *zap.SugaredLogger, hub *hub.Hub) *System {
|
||||||
s := System{log: logging}
|
s := System{log: logging, hub: hub}
|
||||||
s.Initialize()
|
s.Initialize()
|
||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
@ -17,15 +18,16 @@ func (s *System) UpdateLiveInformation() {
|
||||||
s.liveRam()
|
s.liveRam()
|
||||||
s.liveDisk()
|
s.liveDisk()
|
||||||
s.uptime()
|
s.uptime()
|
||||||
|
s.hub.LiveInformationCh <- hub.Message{WsType: hub.System, Message: s.CurrentSystem.Live}
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *System) Initialize() {
|
func (s *System) Initialize() {
|
||||||
s.Static.Host = staticHost()
|
s.CurrentSystem.Static.Host = staticHost()
|
||||||
s.Static.CPU = staticCpu()
|
s.CurrentSystem.Static.CPU = staticCpu()
|
||||||
s.Static.Ram = staticRam()
|
s.CurrentSystem.Static.Ram = staticRam()
|
||||||
s.Static.Disk = staticDisk()
|
s.CurrentSystem.Static.Disk = staticDisk()
|
||||||
go s.UpdateLiveInformation()
|
go s.UpdateLiveInformation()
|
||||||
s.log.Debugw("system updated", "cpu", s.Static.CPU.Name, "arch", s.Static.Host.Architecture)
|
s.log.Debugw("system updated", "cpu", s.CurrentSystem.Static.CPU.Name, "arch", s.CurrentSystem.Static.Host.Architecture)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
package system
|
package system
|
||||||
|
|
||||||
import "go.uber.org/zap"
|
import (
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"godash/hub"
|
||||||
|
)
|
||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
log *zap.SugaredLogger
|
hub *hub.Hub
|
||||||
|
log *zap.SugaredLogger
|
||||||
|
CurrentSystem CurrentSystem
|
||||||
|
}
|
||||||
|
|
||||||
|
type CurrentSystem struct {
|
||||||
Live LiveInformation `json:"live"`
|
Live LiveInformation `json:"live"`
|
||||||
Static StaticInformation `json:"static"`
|
Static StaticInformation `json:"static"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ func (s *System) uptime() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.Live.Uptime.Days = i.Uptime / 84600
|
s.CurrentSystem.Live.Uptime.Days = i.Uptime / 84600
|
||||||
s.Live.Uptime.Hours = uint16((i.Uptime % 86400) / 3600)
|
s.CurrentSystem.Live.Uptime.Hours = uint16((i.Uptime % 86400) / 3600)
|
||||||
s.Live.Uptime.Minutes = uint16(((i.Uptime % 86400) % 3600) / 60)
|
s.CurrentSystem.Live.Uptime.Minutes = uint16(((i.Uptime % 86400) % 3600) / 60)
|
||||||
s.Live.Uptime.Seconds = uint16(((i.Uptime % 86400) % 3600) % 60)
|
s.CurrentSystem.Live.Uptime.Seconds = uint16(((i.Uptime % 86400) % 3600) % 60)
|
||||||
s.Live.Uptime.Percentage = float32((s.Live.Uptime.Minutes*100)+s.Live.Uptime.Seconds) / 60
|
s.CurrentSystem.Live.Uptime.Percentage = float32((s.CurrentSystem.Live.Uptime.Minutes*100)+s.CurrentSystem.Live.Uptime.Seconds) / 60
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package weather
|
package weather
|
||||||
|
|
||||||
import "go.uber.org/zap"
|
import (
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"godash/hub"
|
||||||
|
)
|
||||||
|
|
||||||
type weather struct {
|
type weather struct {
|
||||||
CurrentWeather OpenWeather
|
CurrentWeather OpenWeather
|
||||||
|
hub *hub.Hub
|
||||||
config config
|
config config
|
||||||
log *zap.SugaredLogger
|
log *zap.SugaredLogger
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,15 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/caarlos0/env/v6"
|
"github.com/caarlos0/env/v6"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"godash/hub"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewWeatherService(logging *zap.SugaredLogger) *weather {
|
func NewWeatherService(logging *zap.SugaredLogger, hub *hub.Hub) *weather {
|
||||||
var w = weather{log: logging}
|
var w = weather{log: logging, hub: hub}
|
||||||
if err := env.Parse(&w.config); err != nil {
|
if err := env.Parse(&w.config); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -67,6 +68,7 @@ func (w *weather) updateWeather(interval time.Duration) {
|
||||||
w.log.Debugw("weather updated", "temp", w.CurrentWeather.Temp)
|
w.log.Debugw("weather updated", "temp", w.CurrentWeather.Temp)
|
||||||
}
|
}
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
|
w.hub.LiveInformationCh <- hub.Message{WsType: hub.Weather, Message: w.CurrentWeather}
|
||||||
}
|
}
|
||||||
time.Sleep(interval)
|
time.Sleep(interval)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue