120 lines
2.2 KiB
Go
120 lines
2.2 KiB
Go
package read
|
|
|
|
import (
|
|
"log"
|
|
"sync"
|
|
"time"
|
|
|
|
"git.tek.govt.hu/dowerx/place/api/structs"
|
|
"git.tek.govt.hu/dowerx/place/config"
|
|
"git.tek.govt.hu/dowerx/place/storage"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
var upgrader = websocket.Upgrader{
|
|
ReadBufferSize: 1024,
|
|
WriteBufferSize: 1024,
|
|
}
|
|
|
|
type ConnectionsMap struct {
|
|
sync.Mutex
|
|
Items map[*websocket.Conn]chan structs.Pixel
|
|
}
|
|
|
|
func (c *ConnectionsMap) Send(pixel structs.Pixel) {
|
|
c.Lock()
|
|
for _, v := range c.Items {
|
|
v <- pixel
|
|
}
|
|
c.Unlock()
|
|
}
|
|
|
|
var Connections ConnectionsMap = ConnectionsMap{Items: make(map[*websocket.Conn]chan structs.Pixel)}
|
|
|
|
func Info(c *gin.Context) {
|
|
conf := config.GetConfig()
|
|
c.JSON(200, gin.H{
|
|
"tileSize": conf.TileSize,
|
|
"canvasSize": conf.CanvasSize,
|
|
"timeout": conf.Timeout,
|
|
})
|
|
}
|
|
|
|
func Tile(c *gin.Context) {
|
|
var coords structs.Coordinates
|
|
if c.ShouldBind(&coords) != nil {
|
|
c.AbortWithStatus(400)
|
|
return
|
|
}
|
|
|
|
buffer, err := storage.GetTile(coords.X, coords.Y)
|
|
if err != nil {
|
|
c.AbortWithError(500, err)
|
|
return
|
|
}
|
|
|
|
c.Status(200)
|
|
c.Header("Content-Type", "image/png")
|
|
c.Writer.Write(buffer.Bytes())
|
|
}
|
|
|
|
func Continuous(c *gin.Context) {
|
|
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
Connections.Lock()
|
|
Connections.Items[conn] = make(chan structs.Pixel)
|
|
Connections.Unlock()
|
|
|
|
conn.SetReadDeadline(time.Now().Add(time.Second * 60))
|
|
conn.SetPongHandler(func(string) error {
|
|
conn.SetReadDeadline(time.Now().Add(time.Second * 60))
|
|
return nil
|
|
})
|
|
|
|
// send pings
|
|
go func() {
|
|
ticker := time.NewTicker(30 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for range ticker.C {
|
|
if err := conn.WriteControl(websocket.PingMessage, nil, time.Now().Add(10*time.Second)); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
// defer: close connection, remove channel
|
|
defer func() {
|
|
Connections.Lock()
|
|
for k, v := range Connections.Items {
|
|
if k == conn {
|
|
close(v)
|
|
delete(Connections.Items, k)
|
|
break
|
|
}
|
|
}
|
|
Connections.Unlock()
|
|
conn.Close()
|
|
log.Println("removed connection")
|
|
}()
|
|
|
|
// send updates
|
|
go func() {
|
|
for pixel := range Connections.Items[conn] {
|
|
conn.WriteJSON(pixel)
|
|
}
|
|
}()
|
|
|
|
// read loop to keep the connetion alive
|
|
for {
|
|
_, _, err := conn.ReadMessage()
|
|
if err != nil {
|
|
break
|
|
}
|
|
}
|
|
}
|