diff --git a/cmd/freifunkmanager/main.go b/cmd/freifunkmanager/main.go index 9d5327f..0f6b472 100644 --- a/cmd/freifunkmanager/main.go +++ b/cmd/freifunkmanager/main.go @@ -64,7 +64,7 @@ func main() { go func() { if err := srv.ListenAndServe(); err != nil { - panic(err) + log.Log.Panic(err) } }() diff --git a/runtime/nodes.go b/runtime/nodes.go index 99266ad..8ff20e1 100644 --- a/runtime/nodes.go +++ b/runtime/nodes.go @@ -41,11 +41,16 @@ func (nodes *Nodes) AddNode(n *yanic.Node) { if cNode := nodes.List[node.NodeID]; cNode != nil { cNode.Lastseen = time.Now() - if _, ok := nodes.ToUpdate[node.NodeID]; ok { + cNode.Stats = node.Stats + if uNode, ok := nodes.ToUpdate[node.NodeID]; ok { + uNode.Lastseen = time.Now() + uNode.Stats = node.Stats if nodes.List[node.NodeID].IsEqual(node) { delete(nodes.ToUpdate, node.NodeID) nodes.List[node.NodeID] = node nodes.notify(node, true) + } else { + nodes.notify(uNode, false) } } else { nodes.List[node.NodeID] = node diff --git a/webroot/index.html b/webroot/index.html index d79351d..98f9e9c 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -4,6 +4,7 @@ FreifunkManager + @@ -21,6 +22,7 @@
Karten & Knoten...

+

diff --git a/webroot/js/gui.js b/webroot/js/gui.js index 2e647b7..afe150c 100644 --- a/webroot/js/gui.js +++ b/webroot/js/gui.js @@ -10,9 +10,8 @@ var gui = {}; console.log(store.will()) } gui.disable = function disable(err){ - document.querySelector('.loader').innerHTML += err - + '

'; - console.warn(err); + document.querySelector('.loader p.error').innerHTML = err + + '

'; }; gui.connecting = function connecting(){ diff --git a/webroot/js/socket.js b/webroot/js/socket.js index 8cd3a94..33358f3 100644 --- a/webroot/js/socket.js +++ b/webroot/js/socket.js @@ -1,35 +1,51 @@ -var socket = new WebSocket(config.backend); +var socket = {}; (function(){ - // When the connection is open, send some data to the server - socket.onopen = function () { + + function onerror(err) { + gui.disable("Es besteht ein Verbindungsproblem!"); + console.warn(err); + } + + function onopen() { gui.enable(); - }; + } - // Log errors - socket.onerror = function (err) { - gui.disable(err); - }; - - // Log messages from the server - socket.onmessage = function (e) { + function onmessage(e) { var msg = JSON.parse(e.data); - if(msg.state === "current") { + if(msg.type === "current") { store.updateReal(msg.node); gui.render(); - } else if (msg.state === "to-update") { + } else if (msg.type === "to-update") { store.update(msg.node); gui.render(); } else { gui.disable(e); } - }; + } - socket.sendnode = function(node) { + function onclose(){ + gui.disable("Es besteht ein Verbindungsproblem!
(Automatische Neuverbindung)"); + console.log("socket closed by server"); + setTimeout(connect, 5000); + } + + function sendnode(node) { var msg = {node:node}; var string = JSON.stringify(msg); socket.send(string); - }; + } + + function connect() { + socket = new WebSocket(config.backend); + socket.onopen = onopen; + socket.onerror = onerror; + socket.onmessage = onmessage; + socket.onclose = onclose; + socket.sendnode = sendnode; + } + + connect(); })(); diff --git a/websocket/client.go b/websocket/client.go index b2c4fb1..24a8f73 100644 --- a/websocket/client.go +++ b/websocket/client.go @@ -11,27 +11,25 @@ import ( const channelBufSize = 100 type Client struct { - ip string - ws *websocket.Conn - ch chan *Message - doneCh chan bool -} - -func disconnect(c *Client) { - delete(clients, c.ip) + ip string + ws *websocket.Conn + ch chan *Message + writeQuit chan bool + readQuit chan bool } func NewClient(ip string, ws *websocket.Conn) *Client { if ws == nil { - panic("ws cannot be nil") + log.Log.Panic("ws cannot be nil") } return &Client{ - ws: ws, - ch: make(chan *Message, channelBufSize), - doneCh: make(chan bool), - ip: ip, + ws: ws, + ch: make(chan *Message, channelBufSize), + writeQuit: make(chan bool), + readQuit: make(chan bool), + ip: ip, } } @@ -39,22 +37,15 @@ func (c *Client) Write(msg *Message) { select { case c.ch <- msg: default: - disconnect(c) - log.HTTP(c.ws.Request()).Error("client is disconnected.") + delete(clients, c.ip) + log.HTTP(c.ws.Request()).Error("client disconnected") } } -func (c *Client) Done() { - c.doneCh <- true -} - -func (c *Client) allNodes() { - for _, node := range nodes.List { - c.Write(&Message{State: StateCurrentNode, Node: node}) - } - for _, node := range nodes.ToUpdate { - c.Write(&Message{State: StateUpdateNode, Node: node}) - } +func (c *Client) Close() { + c.writeQuit <- true + c.readQuit <- true + log.HTTP(c.ws.Request()).Info("client disconnecting...") } // Listen Write and Read request via chanel @@ -64,6 +55,22 @@ func (c *Client) Listen() { c.listenRead() } +func (c *Client) allNodes() { + for _, node := range nodes.List { + c.Write(&Message{Type: MessageTypeCurrentNode, Node: node}) + } + for _, node := range nodes.ToUpdate { + c.Write(&Message{Type: MessageTypeUpdateNode, Node: node}) + } +} + +func (c *Client) handleMassage(msg *Message) { + switch msg.Type { + case MessageTypeUpdateNode: + nodes.UpdateNode(msg.Node) + } +} + // Listen write request via chanel func (c *Client) listenWrite() { for { @@ -71,9 +78,10 @@ func (c *Client) listenWrite() { case msg := <-c.ch: websocket.JSON.Send(c.ws, msg) - case <-c.doneCh: - disconnect(c) - c.doneCh <- true + case <-c.writeQuit: + close(c.ch) + close(c.writeQuit) + delete(clients, c.ip) return } } @@ -84,22 +92,22 @@ func (c *Client) listenRead() { for { select { - case <-c.doneCh: - disconnect(c) - c.doneCh <- true + case <-c.readQuit: + close(c.readQuit) + delete(clients, c.ip) return default: var msg Message err := websocket.JSON.Receive(c.ws, &msg) if err == io.EOF { - log.HTTP(c.ws.Request()).Info("disconnect") - c.doneCh <- true + close(c.readQuit) + c.writeQuit <- true + return } else if err != nil { log.HTTP(c.ws.Request()).Error(err) } else { - log.HTTP(c.ws.Request()).Info("recieve nodeupdate") - nodes.UpdateNode(msg.Node) + c.handleMassage(&msg) } } } diff --git a/websocket/msg.go b/websocket/msg.go index e3f716a..daeec1f 100644 --- a/websocket/msg.go +++ b/websocket/msg.go @@ -3,11 +3,11 @@ package websocket import "github.com/FreifunkBremen/freifunkmanager/runtime" type Message struct { - State string `json:"state"` - Node *runtime.Node `json:"node"` + Type string `json:"type"` + Node *runtime.Node `json:"node"` } const ( - StateUpdateNode = "to-update" - StateCurrentNode = "current" + MessageTypeUpdateNode = "to-update" + MessageTypeCurrentNode = "current" ) diff --git a/websocket/server.go b/websocket/server.go index 7a520a7..a7c3ec5 100644 --- a/websocket/server.go +++ b/websocket/server.go @@ -12,48 +12,42 @@ import ( var nodes *runtime.Nodes var clients map[string]*Client -var quit chan struct{} func Start(nodeBind *runtime.Nodes) { nodes = nodeBind clients = make(map[string]*Client) - quit = make(chan struct{}) http.Handle("/websocket", websocket.Handler(func(ws *websocket.Conn) { + r := ws.Request() + ip := httpLib.GetRemoteIP(r) + defer func() { ws.Close() + delete(clients, ip) + log.HTTP(r).Info("client disconnected") }() - r := ws.Request() + log.HTTP(r).Infof("new client") - ip := httpLib.GetRemoteIP(r) + client := NewClient(ip, ws) clients[ip] = client client.Listen() + })) nodes.AddNotify(Notify) - /* - for { - select { - case <-quit: - return - } - }*/ } func Notify(node *runtime.Node, real bool) { - state := StateUpdateNode + msgType := MessageTypeUpdateNode if real { - state = StateCurrentNode + msgType = MessageTypeCurrentNode } for _, c := range clients { - c.Write(&Message{State: state, Node: node}) + c.Write(&Message{Type: msgType, Node: node}) } } func Close() { - for _, c := range clients { - c.Done() - } - close(quit) + log.Log.Infof("websocket stopped with %d clients", len(clients)) } diff --git a/yanic/dial.go b/yanic/dial.go index 9bece08..87b16eb 100644 --- a/yanic/dial.go +++ b/yanic/dial.go @@ -38,9 +38,11 @@ func (d *Dialer) Start() { go d.parser() } func (d *Dialer) Close() { - close(d.quit) - d.conn.Close() - close(d.queue) + if d != nil { + d.conn.Close() + close(d.queue) + close(d.quit) + } } func (d *Dialer) reciever() {