[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blogs-en-1-1-all-pinned-messages-websocket-chat-all--*":3,"academy-blog-translations-qjpndekyzivfoi4":51},{"data":4,"page":39,"perPage":39,"totalItems":39,"totalPages":39},[5],{"alt":6,"collectionId":7,"collectionName":8,"content":9,"cover_image":10,"cover_image_path":11,"created":12,"created_by":13,"expand":14,"id":45,"keywords":46,"locale":21,"published_at":47,"scheduled_at":13,"school_blog":43,"short_description":48,"slug":49,"status":41,"title":6,"updated":50,"updated_by":13,"views":44},"EP.43 Adding Pinned Messages Feature in WebSocket Chat","sclblg987654321","school_blog_translations","\u003Ch3>Why Have a Pinned Messages Feature?\u003C\u002Fh3>\u003Cp>\u003Cstrong>Pinned Messages\u003C\u002Fstrong> are a feature that allows users to save important messages for later reference, offering several benefits:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cstrong>Preservation of Important Messages: \u003C\u002Fstrong>Keeps crucial information from getting lost in high-volume conversations.\u003C\u002Fli>\u003Cli>\u003Cstrong>Announcement Channel:\u003C\u002Fstrong> Serves as a way to highlight important announcements for groups or teams.\u003C\u002Fli>\u003Cli>\u003Cstrong>Easier Access to Important Information:\u003C\u002Fstrong> Allows users to quickly find and access key messages.\u003C\u002Fli>\u003C\u002Ful>\u003Ch3>Structure of the Pinned Messages System in WebSocket Chat\u003C\u002Fh3>\u003Col>\u003Cli>\u003Cstrong>WebSocket Server:\u003C\u002Fstrong> Handles the reception and transmission of pinned message statuses.\u003C\u002Fli>\u003Cli>\u003Cstrong>Database: \u003C\u002Fstrong>Stores data about the messages that have been pinned.\u003C\u002Fli>\u003Cli>\u003Cstrong>Frontend (Client-Side):\u003C\u002Fstrong> Displays the list of pinned messages to users.\u003C\u002Fli>\u003C\u002Fol>\u003Ch3>Adding the Pinned Messages Feature to the WebSocket Server\u003C\u002Fh3>\u003Ch4>1. Upgrade the WebSocket Server to Support Pinned Messages\u003C\u002Fh4>\u003Cp>File: \u003Ccode>\u003Cspan>websocket_server.go\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">package main\n\nimport (\n    \"encoding\u002Fjson\"\n    \"fmt\"\n    \"net\u002Fhttp\"\n    \"sync\"\n\n    \"github.com\u002Fgorilla\u002Fwebsocket\"\n)\n\ntype PinnedMessage struct {\n    MessageID int    `json:\"messageID\"`\n    RoomID    int    `json:\"roomID\"`\n    PinnedBy  string `json:\"pinnedBy\"`\n}\n\nvar upgrader = websocket.Upgrader{\n    CheckOrigin: func(r *http.Request) bool { return true },\n}\n\nvar (\n    clients   = make(map[*websocket.Conn]bool)\n    pinned    = make(map[int]PinnedMessage)\n    broadcast = make(chan PinnedMessage)\n    mu        sync.Mutex\n)\n\nfunc handleConnections(w http.ResponseWriter, r *http.Request) {\n    conn, _ := upgrader.Upgrade(w, r, nil)\n    defer conn.Close()\n    clients[conn] = true\n\n    for {\n        var pinnedMsg PinnedMessage\n        err := conn.ReadJSON(&amp;pinnedMsg)\n        if err != nil {\n            delete(clients, conn)\n            break\n        }\n        broadcast &lt;- pinnedMsg\n    }\n}\n\nfunc handleMessages() {\n    for {\n        pinnedMsg := &lt;-broadcast\n        mu.Lock()\n        pinned[pinnedMsg.MessageID] = pinnedMsg\n        mu.Unlock()\n        \n        for client := range clients {\n            err := client.WriteJSON(pinnedMsg)\n            if err != nil {\n                client.Close()\n                delete(clients, client)\n            }\n        }\n    }\n}\n\nfunc main() {\n    http.HandleFunc(\"\u002Fws\", handleConnections)\n    go handleMessages()\n    fmt.Println(\"WebSocket Server Running on Port 8080\")\n    http.ListenAndServe(\":8080\", nil)\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3>2. Adding Pinned Messages Functionality in the Frontend (Client-Side)\u003C\u002Fh3>\u003Cp>File: \u003Ccode>\u003Cspan>client.js\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">const socket = new WebSocket(\"ws:\u002F\u002Flocalhost:8080\u002Fws\");\nconst pinnedContainer = document.getElementById(\"pinned-messages\");\n\nsocket.onmessage = (event) =&gt; {\n    const data = JSON.parse(event.data);\n    if (data.messageID) {\n        const pinnedElement = document.createElement(\"p\");\n        pinnedElement.innerText = `Pinned Message: ${data.messageID} by ${data.pinnedBy}`;\n        pinnedContainer.appendChild(pinnedElement);\n    }\n};\n\nfunction pinMessage(messageID) {\n    socket.send(JSON.stringify({ roomID: 1, messageID, pinnedBy: \"JohnDoe\" }));\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3>Displaying Pinned Messages on the UI\u003C\u002Fh3>\u003Cp>File: \u003Ccode>\u003Cspan>index.html\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">&lt;div id=\"pinned-messages\"&gt;&lt;\u002Fdiv&gt;\n&lt;button onclick=\"pinMessage(1)\"&gt;Pin Message 1&lt;\u002Fbutton&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3 data-pm-slice=\"1 1 []\">\u003Cspan>\u003Cstrong>3. Testing the System\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Col data-spread=\"false\">\u003Cli>\u003Cspan>\u003Cstrong>Run the WebSocket Server\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fli>\u003C\u002Fol>\u003Cpre>\u003Ccode class=\"language-plaintext\">go run websocket_server.go\u003C\u002Fcode>\u003C\u002Fpre>\u003Col data-spread=\"false\" start=\"2\">\u003Cli>\u003Cspan>\u003Cstrong>Open Multiple Browser Tabs and Pin Messages\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fli>\u003Cli>\u003Cspan>\u003Cstrong>Observe Results at WebSocket Server and UI\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fli>\u003C\u002Fol>\u003Ch3>Challenge!\u003C\u002Fh3>\u003Cp>Try adding \u003Cstrong>an Unpin Messages feature\u003C\u002Fstrong>, allowing users to remove the pin from messages they no longer want to keep pinned.\u003C\u002Fp>\u003Chr>\u003Ch3>Next EP\u003C\u002Fh3>\u003Cp>In \u003Cstrong>EP.44,\u003C\u002Fstrong> we will add \u003Cstrong>a Feature to Display the Number of Online Users in the WebSocket Chat! \u003C\u002Fstrong>🚀\u003C\u002Fp>","58_11zon_zxo4echh9i.webp","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002F5x3meflcxal39yb\u002F58_11zon_zxo4echh9i.webp","2026-03-04 08:50:58.855Z","",{"locale":15,"school_blog":25},{"code":16,"collectionId":17,"collectionName":18,"created":19,"flag":20,"id":21,"is_default":22,"label":23,"updated":24},"en","pbc_1989393366","locales","2026-01-22 11:00:02.726Z","twemoji:flag-united-states","qv9c1llfov2d88z",false,"English","2026-04-10 15:42:46.825Z",{"category":26,"collectionId":27,"collectionName":28,"expand":29,"id":43,"views":44},"wqxt7ag2gn7xcmk","pbc_2105096300","school_blogs",{"category":30},{"blogIds":31,"collectionId":32,"collectionName":33,"created":34,"created_by":13,"id":26,"image":35,"image_alt":13,"image_path":36,"label":37,"name":38,"priority":39,"publish_at":40,"scheduled_at":13,"status":41,"updated":42,"updated_by":13},[],"sclcatblg987654321","school_category_blogs","2026-03-04 08:33:53.210Z","59ty92ns80w_15oc1implw.png","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclcatblg987654321\u002Fwqxt7ag2gn7xcmk\u002F59ty92ns80w_15oc1implw.png",{"en":38,"th":38},"Golang The Series",1,"2026-03-16 04:39:38.440Z","published","2026-04-25 02:32:15.470Z","qjpndekyzivfoi4",207,"5x3meflcxal39yb",[],"2025-03-24 01:51:27.917Z","Learn how to implement the Pinned Messages feature in WebSocket Chat, allowing users to save important messages for later reference, with support for real-time notifications when messages are pinned.","pinned-messages-websocket-chat","2026-04-22 07:11:42.291Z",{"en":49}]