diff --git a/contrib/ui/mesh-ui/ui/assets/mesh-ui-es5.js b/contrib/ui/mesh-ui/ui/assets/mesh-ui-es5.js index d8916fcc..82c308a5 100644 --- a/contrib/ui/mesh-ui/ui/assets/mesh-ui-es5.js +++ b/contrib/ui/mesh-ui/ui/assets/mesh-ui-es5.js @@ -299,8 +299,6 @@ ui.getConnectedPeers = function () { ui.updateConnectedPeersHandler = function (peers) { ui.updateStatus(peers); - ui.updateSpeed(peers); - ui.updateCoordsInfo(); $("peers").innerText = ""; if (peers) { var regexStrip = /%[^\]]*/gm; @@ -381,7 +379,7 @@ ui.updateSelfInfo = function () { return ui.getSelfInfo().then(function (info) { $("ipv6").innerText = info.address; $("subnet").innerText = info.subnet; - $("coordinates").innerText = ''.concat('[',info.coords.join(' '),']'); + $("coordinates").innerText = ''.concat('[', info.coords.join(' '), ']'); $("pub_key").innerText = info.key; $("priv_key").innerText = info.private_key; $("ipv6").innerText = info.address; @@ -391,16 +389,6 @@ ui.updateSelfInfo = function () { }); }; -ui.updateCoordsInfo = function () { - return ui.getSelfInfo().then(function (info) { - $("coordinates").innerText = ''.concat('[',info.coords.join(' '),']'); - }).catch(function (error) { - $("ipv6").innerText = error.message; - }); -}; - -ui.sse = new EventSource('/api/sse'); - function main() { window.addEventListener("load", function () { @@ -412,6 +400,8 @@ function main() { ui.updateSelfInfo(); + ui.sse = new EventSource('/api/sse'); + ui.sse.addEventListener("ping", function (e) { var data = JSON.parse(e.data); setPingValue(data.peer, data.value); @@ -420,7 +410,16 @@ function main() { ui.sse.addEventListener("peers", function (e) { ui.updateConnectedPeersHandler(JSON.parse(e.data)); }); + + ui.sse.addEventListener("rxtx", function (e) { + ui.updateSpeed(JSON.parse(e.data)); + }); + + ui.sse.addEventListener("coord", function (e) { + var coords = JSON.parse(e.data); + $("coordinates").innerText = ''.concat('[', coords.join(' '), ']'); + }); }); } -main(); +main(); \ No newline at end of file diff --git a/contrib/ui/mesh-ui/ui/assets/mesh-ui.css b/contrib/ui/mesh-ui/ui/assets/mesh-ui.css index 0565d85b..9a12e8e2 100644 --- a/contrib/ui/mesh-ui/ui/assets/mesh-ui.css +++ b/contrib/ui/mesh-ui/ui/assets/mesh-ui.css @@ -96,6 +96,7 @@ footer { #version { padding-left: 20px; + padding-right: 20px; } #status { diff --git a/contrib/ui/mesh-ui/ui/assets/mesh-ui.js b/contrib/ui/mesh-ui/ui/assets/mesh-ui.js index 8caa39bc..36b84cd4 100644 --- a/contrib/ui/mesh-ui/ui/assets/mesh-ui.js +++ b/contrib/ui/mesh-ui/ui/assets/mesh-ui.js @@ -286,8 +286,6 @@ ui.getConnectedPeers = () => ui.updateConnectedPeersHandler = (peers) => { ui.updateStatus(peers); - ui.updateSpeed(peers); - ui.updateCoordsInfo(); $("peers").innerText = ""; if(peers) { const regexStrip = /%[^\]]*/gm; @@ -368,16 +366,6 @@ ui.updateSelfInfo = () => $("ipv6").innerText = error.message; }); -ui.updateCoordsInfo = function () { - return ui.getSelfInfo().then(function (info) { - $("coordinates").innerText = ''.concat('[',info.coords.join(' '),']'); - }).catch(function (error) { - $("ipv6").innerText = error.message; - }); -}; - -ui.sse = new EventSource('/api/sse'); - function main() { window.addEventListener("load", () => { @@ -386,7 +374,8 @@ function main() { ui.getAllPeers().then(() => ui.updateConnectedPeers()); ui.updateSelfInfo(); - //setInterval(ui.updateSelfInfo, 5000); + + ui.sse = new EventSource('/api/sse'); ui.sse.addEventListener("ping", (e) => { let data = JSON.parse(e.data); @@ -397,6 +386,15 @@ function main() { ui.updateConnectedPeersHandler(JSON.parse(e.data)); }) + ui.sse.addEventListener("rxtx", (e) => { + ui.updateSpeed(JSON.parse(e.data)); + }) + + ui.sse.addEventListener("coord", (e) => { + let coords = JSON.parse(e.data); + $("coordinates").innerText = ''.concat('[',coords.join(' '),']'); + }) + }); } diff --git a/src/restapi/rest_server.go b/src/restapi/rest_server.go index 6213248d..968147ce 100644 --- a/src/restapi/rest_server.go +++ b/src/restapi/rest_server.go @@ -24,7 +24,7 @@ import ( type ServerEvent struct { Event string - Data string + Data []byte } type RestServerCfg struct { @@ -40,6 +40,7 @@ type RestServer struct { listenUrl *url.URL serverEvents chan ServerEvent serverEventNextId int + updateTimer *time.Timer docFsType string } @@ -93,7 +94,7 @@ func NewRestServer(cfg RestServerCfg) (*RestServer, error) { } select { - case a.serverEvents <- ServerEvent{Event: "peers", Data: string(b)}: + case a.serverEvents <- ServerEvent{Event: "peers", Data: b}: default: } }) @@ -281,23 +282,40 @@ func (a *RestServer) apiSseHandler(w http.ResponseWriter, r *http.Request) { case v := <-a.serverEvents: fmt.Fprintln(w, "id:", a.serverEventNextId) fmt.Fprintln(w, "event:", v.Event) - fmt.Fprintln(w, "data:", v.Data) + fmt.Fprintln(w, "data:", string(v.Data)) fmt.Fprintln(w) //end of event a.serverEventNextId += 1 default: break Loop } } + if a.updateTimer != nil { + select { + case <-a.updateTimer.C: + go a.sendSseUpdate() + a.updateTimer.Reset(time.Second * 5) + default: + } + } else { + a.updateTimer = time.NewTimer(time.Second * 5) + } default: http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) } } +func (a *RestServer) sendSseUpdate() { + rx, tx := a.getPeersRxTxBytes() + a.serverEvents <- ServerEvent{Event: "rxtx", Data: []byte(fmt.Sprintf(`[{"bytes_recvd":%d,"bytes_sent":%d}]`, rx, tx))} + data, _ := json.Marshal(a.Core.GetSelf().Coords) + a.serverEvents <- ServerEvent{Event: "coord", Data: data} +} + func (a *RestServer) ping(peers []string) { for _, u := range peers { go func(u string) { data, _ := json.Marshal(map[string]string{"peer": u, "value": strconv.FormatInt(check(u), 10)}) - a.serverEvents <- ServerEvent{Event: "ping", Data: string(data)} + a.serverEvents <- ServerEvent{Event: "ping", Data: data} }(u) } } @@ -315,3 +333,15 @@ func check(peer string) int64 { d := time.Since(t) return d.Milliseconds() } + +func (a *RestServer) getPeersRxTxBytes() (uint64, uint64) { + var rx uint64 + var tx uint64 + + peers := a.Core.GetPeers() + for _, p := range peers { + rx += p.RXBytes + tx += p.TXBytes + } + return rx, tx +}