diff --git a/cmd/mtwebmapper/forwardupdates.go b/cmd/mtwebmapper/forwardupdates.go index 8f5f3f9..f2ba8e9 100644 --- a/cmd/mtwebmapper/forwardupdates.go +++ b/cmd/mtwebmapper/forwardupdates.go @@ -17,7 +17,7 @@ type websocketForwarder struct { upgrader *websocket.Upgrader register chan *connection unregister chan *connection - broadcast chan map[xz]bool + broadcast chan msg connections map[*connection]bool } @@ -26,13 +26,18 @@ type connection struct { send chan []byte } +type msg struct { + tiles map[xz]bool + pls []*player +} + func newWebsocketForwarder() *websocketForwarder { upgrader := &websocket.Upgrader{ReadBufferSize: 512, WriteBufferSize: 2048} return &websocketForwarder{ upgrader: upgrader, register: make(chan *connection), unregister: make(chan *connection), - broadcast: make(chan map[xz]bool), + broadcast: make(chan msg), connections: make(map[*connection]bool)} } @@ -46,26 +51,34 @@ func (wsf *websocketForwarder) run() { delete(wsf.connections, c) close(c.send) } - case changes := <-wsf.broadcast: + case message := <-wsf.broadcast: if len(wsf.connections) == 0 { continue } - // Do the JSON encoding this late to save - // some CPU cyles if no client is connected. - xzs := make([]xz, 0, len(changes)) - for xz := range changes { - xzs = append(xzs, xz) + encMsg := map[string]interface{}{} + + if tiles := message.tiles; tiles != nil { + xzs := make([]xz, 0, len(tiles)) + for xz := range tiles { + xzs = append(xzs, xz) + } + encMsg["tiles"] = xzs } + + if message.pls != nil { + encMsg["players"] = message.pls + } + var buf bytes.Buffer encoder := json.NewEncoder(&buf) - if err := encoder.Encode(xzs); err != nil { + if err := encoder.Encode(encMsg); err != nil { log.Printf("encoding changes failed: %s\n", err) continue } - msg := buf.Bytes() + m := buf.Bytes() for c := range wsf.connections { select { - case c.send <- msg: + case c.send <- m: default: delete(wsf.connections, c) close(c.send) @@ -89,7 +102,11 @@ func (wsf *websocketForwarder) ServeHTTP(rw http.ResponseWriter, r *http.Request } func (wsf *websocketForwarder) BaseTilesUpdated(changes map[xz]bool) { - wsf.broadcast <- changes + wsf.broadcast <- msg{tiles: changes} +} + +func (wsf *websocketForwarder) BroadcastPlayers(pls []*player) { + wsf.broadcast <- msg{pls: pls} } func (c *connection) writer() { diff --git a/cmd/mtwebmapper/players.go b/cmd/mtwebmapper/players.go index 5f575e4..8cfeb5b 100644 --- a/cmd/mtwebmapper/players.go +++ b/cmd/mtwebmapper/players.go @@ -77,7 +77,10 @@ func (ps *players) run() { ps.mu.Lock() ps.pls = pls ps.mu.Unlock() - // TODO: Implement websocket broadcast. + if ps.wsf != nil { + // TODO: Throttle this! + ps.wsf.BroadcastPlayers(pls) + } } } diff --git a/cmd/mtwebmapper/web/js/auto-update.js b/cmd/mtwebmapper/web/js/auto-update.js index 9c805e2..e1b6bfb 100644 --- a/cmd/mtwebmapper/web/js/auto-update.js +++ b/cmd/mtwebmapper/web/js/auto-update.js @@ -47,13 +47,18 @@ L.Control.AutoUpdate = L.Control.extend({ if (!(typeof json === "string")) { return invalidateAll; } - var tiles; + var msg; try { - tiles = JSON.parse(json); + msg = JSON.parse(json); } catch (err) { return invalidateAll; } + var tiles = msg.tiles; + if !tiles { + continue; + } + var pyramid = new Array(9); var last = new Object(); pyramid[8] = last;