From f9ba885019cb08ad8762e2284221a5fc67317445 Mon Sep 17 00:00:00 2001 From: JurajKubrican Date: Mon, 30 Dec 2024 13:42:52 +0100 Subject: [PATCH] Robust websockets --- src/main.go | 55 +++++++++++++++++------- views/boxes.html | 7 +--- views/index.html | 107 +++++++++++++++++++++++++++++++---------------- 3 files changed, 114 insertions(+), 55 deletions(-) diff --git a/src/main.go b/src/main.go index 9e945b8..7143212 100644 --- a/src/main.go +++ b/src/main.go @@ -5,6 +5,7 @@ import ( "io" "net/http" "strconv" + "strings" "sync" "github.com/labstack/echo/v4" @@ -98,33 +99,44 @@ func main() { 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" +func sendUpdate(index int, checked bool) { + message := formatMessage(index, checked) + broadcastMessage(message) +} - index, err := strconv.Atoi(id) - if err != nil { - return c.String(http.StatusBadRequest, "Invalid ID") - } - - boxes[index] = checked - - message := strconv.Itoa(index) +func formatMessage(index int, checked bool) string { + message := "u:" + strconv.Itoa(index) if checked { message += ":+" } else { message += ":-" } + return message +} - broadcastMessage(message) +func handleMessage(msg string, ws *websocket.Conn) error { + if strings.Contains(msg, "u:") { + parts := strings.Split(msg, ":") + index, err := strconv.Atoi(parts[1]) + if err != nil { + return err + } + checked := parts[2] == "+" - return c.JSON(200, "[]") + boxes[index] = checked + + sendUpdate(index, checked) + } + if strings.Contains(msg, "ping") { + len := len(wsConnections) + websocket.Message.Send(ws, "pong-"+strconv.Itoa(len)) + } + return nil } func initWs(c echo.Context) error { @@ -133,6 +145,18 @@ func initWs(c echo.Context) error { wsConnections[ws] = true wsMutex.Unlock() + initialState := "i:" + for index, checked := range boxes { + if checked { + initialState += strconv.Itoa(index) + ";" + } + } + + if err := websocket.Message.Send(ws, initialState); err != nil { + log.Errorf("Failed to send initial data: %v", err) + return + } + for { var msg string if err := websocket.Message.Receive(ws, &msg); err != nil { @@ -142,7 +166,10 @@ func initWs(c echo.Context) error { ws.Close() break } + handleMessage(msg, ws) + log.Infof("Received message: %s", msg) } }).ServeHTTP(c.Response(), c.Request()) + return nil } diff --git a/views/boxes.html b/views/boxes.html index 92abf09..a51741a 100644 --- a/views/boxes.html +++ b/views/boxes.html @@ -1,10 +1,5 @@ {{block "boxes" .}} {{range $index, $value := .}} - + {{end}} {{end}} \ No newline at end of file diff --git a/views/index.html b/views/index.html index 4163d0a..1061d49 100644 --- a/views/index.html +++ b/views/index.html @@ -1,56 +1,93 @@ {{block "index" .}} - - - + + + Home - - + +
-
-
- {{template "boxes" .Boxes}} -
-
+
+
{{template "boxes" .Boxes}}
+
- + {{end}} - - - -