websocket checkboxes
This commit is contained in:
90
src/main.go
90
src/main.go
@@ -4,10 +4,14 @@ import (
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/labstack/gommon/log"
|
||||
"github.com/russross/blackfriday/v2"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
type Templates struct {
|
||||
@@ -25,22 +29,42 @@ func NewTemplates() *Templates {
|
||||
}
|
||||
|
||||
type Page struct {
|
||||
Boxes map[int]bool
|
||||
}
|
||||
|
||||
func newPage() Page {
|
||||
return Page{}
|
||||
func newPage(boxes map[int]bool) Page {
|
||||
return Page{
|
||||
Boxes: boxes,
|
||||
}
|
||||
}
|
||||
|
||||
type Article struct {
|
||||
Content string
|
||||
Content template.HTML
|
||||
}
|
||||
|
||||
func newArticle(content string) Article {
|
||||
func newArticle(content template.HTML) Article {
|
||||
return Article{
|
||||
Content: content,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
wsConnections = make(map[*websocket.Conn]bool)
|
||||
wsMutex sync.Mutex
|
||||
boxes = make(map[int]bool, 1000)
|
||||
)
|
||||
|
||||
func broadcastMessage(message string) {
|
||||
wsMutex.Lock()
|
||||
defer wsMutex.Unlock()
|
||||
for conn := range wsConnections {
|
||||
if err := websocket.Message.Send(conn, message); err != nil {
|
||||
conn.Close()
|
||||
delete(wsConnections, conn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
e := echo.New()
|
||||
e.Renderer = NewTemplates()
|
||||
@@ -48,7 +72,11 @@ func main() {
|
||||
e.Logger.SetLevel(log.DEBUG)
|
||||
e.Use(middleware.Logger())
|
||||
|
||||
page := newPage()
|
||||
for i := 0; i < 1000; i++ {
|
||||
boxes[i] = false
|
||||
}
|
||||
|
||||
page := newPage(boxes)
|
||||
|
||||
e.Static("/images", "images")
|
||||
e.Static("/css", "css")
|
||||
@@ -57,16 +85,64 @@ func main() {
|
||||
return c.Render(200, "index", page)
|
||||
})
|
||||
|
||||
e.GET("/we-are-here", func(c echo.Context) error {
|
||||
e.GET("/blog", func(c echo.Context) error {
|
||||
// Log a test message
|
||||
e.Logger.Info("Test log: /we-are-here endpoint called")
|
||||
|
||||
msg := getNotes(c, e.Logger)
|
||||
e.Logger.Info(msg)
|
||||
|
||||
article := newArticle(" content")
|
||||
htmlContent := blackfriday.Run([]byte(msg))
|
||||
|
||||
article := newArticle(template.HTML(string(htmlContent)))
|
||||
return c.Render(http.StatusOK, "article", article)
|
||||
})
|
||||
|
||||
e.POST("/box/:id", updateBoxes)
|
||||
e.GET("/ws", initWs)
|
||||
|
||||
e.Logger.Fatal(e.Start(":54321"))
|
||||
}
|
||||
|
||||
func updateBoxes(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
checked := c.FormValue("checked") == "on"
|
||||
|
||||
index, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
return c.String(http.StatusBadRequest, "Invalid ID")
|
||||
}
|
||||
|
||||
boxes[index] = checked
|
||||
|
||||
message := strconv.Itoa(index)
|
||||
if checked {
|
||||
message += ":+"
|
||||
} else {
|
||||
message += ":-"
|
||||
}
|
||||
|
||||
broadcastMessage(message)
|
||||
|
||||
return c.JSON(200, "[]")
|
||||
}
|
||||
|
||||
func initWs(c echo.Context) error {
|
||||
websocket.Handler(func(ws *websocket.Conn) {
|
||||
wsMutex.Lock()
|
||||
wsConnections[ws] = true
|
||||
wsMutex.Unlock()
|
||||
|
||||
for {
|
||||
var msg string
|
||||
if err := websocket.Message.Receive(ws, &msg); err != nil {
|
||||
wsMutex.Lock()
|
||||
delete(wsConnections, ws)
|
||||
wsMutex.Unlock()
|
||||
ws.Close()
|
||||
break
|
||||
}
|
||||
}
|
||||
}).ServeHTTP(c.Response(), c.Request())
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user