[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blogs-en-1-1-all-online-users-websocket-chat-all--*":3,"academy-blog-translations-hid8s1ph5iqlgp3":99},{"data":4,"page":87,"perPage":87,"totalItems":87,"totalPages":87},[5],{"alt":6,"collectionId":7,"collectionName":8,"content":9,"cover_image":10,"cover_image_path":11,"created":12,"created_by":13,"expand":14,"id":93,"keywords":94,"locale":69,"published_at":95,"scheduled_at":13,"school_blog":91,"short_description":96,"slug":97,"status":89,"title":6,"updated":98,"updated_by":13,"views":92},"EP.44 Adding Active Users Feature in WebSocket Chat","sclblg987654321","school_blog_translations","\u003Ch3>\u003Cspan>\u003Cstrong>Why Have a Feature to Display the Number of Online Users?\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp>\u003Cspan>The Active Users feature, which shows the number of users currently online, enhances the chat experience by allowing users to see who is available for interaction. This feature provides several benefits:\u003C\u002Fspan>\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cstrong>Real-Time Interaction: \u003C\u002Fstrong>Users can see which of their chat companions are online, making conversations more immediate and engaging.\u003C\u002Fli>\u003Cli>\u003Cstrong>Dynamic User Count:\u003C\u002Fstrong> It allows for the display of the number of active users in real-time.\u003C\u002Fli>\u003Cli>\u003Cstrong>Ideal for Community or Support Chats:\u003C\u002Fstrong> Facilitates quick responses in environments where timely communication is essential.\u003C\u002Fli>\u003C\u002Ful>\u003Ch3>\u003Cspan>\u003Cstrong>Structure of the Online User Count System in WebSocket Chat\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Col>\u003Cli>\u003Cstrong>WebSocket Server:\u003C\u002Fstrong> Monitors the online status of users and notifies others when changes occur.\u003C\u002Fli>\u003Cli>\u003Cstrong>Database (Optional):\u003C\u002Fstrong> Can be used to store user online status data for long-term tracking.\u003C\u002Fli>\u003Cli>\u003Cstrong>Frontend (Client-Side):\u003C\u002Fstrong> Displays the number of online users and updates in real-time.\u003C\u002Fli>\u003C\u002Fol>\u003Ch3>\u003Cspan>\u003Cstrong>Adding the Active Users Feature to the WebSocket Server\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Ch4>\u003Cspan>\u003Cstrong>1. Upgrade the WebSocket Server to Support Online Status Tracking\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh4>\u003Cp>\u003Cspan>File \u003C\u002Fspan>\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    \"github.com\u002Fgorilla\u002Fwebsocket\"\n)\n\ntype UserStatus struct {\n    Username string `json:\"username\"`\n    Online   bool   `json:\"online\"`\n}\n\nvar upgrader = websocket.Upgrader{\n    CheckOrigin: func(r *http.Request) bool { return true },\n}\n\nvar (\n    clients      = make(map[*websocket.Conn]string)\n    onlineUsers  = make(map[string]bool)\n    broadcast    = make(chan UserStatus)\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    \n    var username string = r.URL.Query().Get(\"username\")\n    \n    mu.Lock()\n    clients[conn] = username\n    onlineUsers[username] = true\n    mu.Unlock()\n    \n    broadcast &lt;- UserStatus{Username: username, Online: true}\n    \n    for {\n        _, _, err := conn.ReadMessage()\n        if err != nil {\n            mu.Lock()\n            delete(clients, conn)\n            delete(onlineUsers, username)\n            mu.Unlock()\n            broadcast &lt;- UserStatus{Username: username, Online: false}\n            break\n        }\n    }\n}\n\nfunc handleMessages() {\n    for {\n        status := &lt;-broadcast\n        fmt.Printf(\"User %s is now %s\\n\", status.Username, map[bool]string{true: \"online\", false: \"offline\"}[status.Online])\n        \n        for client := range clients {\n            err := client.WriteJSON(status)\n            if err != nil {\n                client.Close()\n                mu.Lock()\n                delete(clients, client)\n                mu.Unlock()\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>\u003Cspan>\u003Cstrong>2. Adding Active Users Functionality in the Frontend (Client-Side)\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp>\u003Cspan>File \u003C\u002Fspan>\u003Ccode>\u003Cspan>client.js\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">const username = prompt(\"Enter your username:\");\nconst socket = new WebSocket(`ws:\u002F\u002Flocalhost:8080\u002Fws?username=${username}`);\nconst onlineUsersContainer = document.getElementById(\"online-users\");\n\nsocket.onmessage = (event) =&gt; {\n    const data = JSON.parse(event.data);\n    updateOnlineUsers(data.username, data.online);\n};\n\nfunction updateOnlineUsers(username, online) {\n    let userElement = document.getElementById(`user-${username}`);\n    if (!userElement) {\n        userElement = document.createElement(\"p\");\n        userElement.id = `user-${username}`;\n        onlineUsersContainer.appendChild(userElement);\n    }\n    userElement.innerText = `${username} is ${online ? \"Online\" : \"Offline\"}`;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3>\u003Cspan>\u003Cstrong>Displaying Active Users on the UI\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fh3>\u003Cp>\u003Cspan>File \u003C\u002Fspan>\u003Ccode>\u003Cspan>index.html\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">&lt;div id=\"online-users\"&gt;&lt;\u002Fdiv&gt;\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3>\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 Log in with different usernames\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 a Last Seen feature to display when a user was last active. This will allow others to know when the user was last online, even if they are currently offline.\u003C\u002Fp>\u003Chr>\u003Ch3>Next EP\u003C\u002Fh3>\u003Cp>In EP.45, we will add a Notification System for When New Users Join the WebSocket Chat! 🚀\u003C\u002Fp>","60_11zon_coh2cet383.webp","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002Fqf7vlwj163t9xut\u002F60_11zon_coh2cet383.webp","2026-03-04 08:50:58.326Z","",{"keywords":15,"locale":63,"school_blog":73},[16,23,28,33,38,43,48,53,58],{"collectionId":17,"collectionName":18,"created":19,"created_by":13,"id":20,"name":21,"updated":22,"updated_by":13},"sclkey987654321","school_keywords","2026-03-04 08:50:56.957Z","8fdbu2zxdum36wl","Online Users","2026-04-10 16:14:30.588Z",{"collectionId":17,"collectionName":18,"created":24,"created_by":13,"id":25,"name":26,"updated":27,"updated_by":13},"2026-03-04 08:34:00.920Z","ecac9y661or1xka","WebSocket","2026-04-10 16:08:05.227Z",{"collectionId":17,"collectionName":18,"created":29,"created_by":13,"id":30,"name":31,"updated":32,"updated_by":13},"2026-03-04 08:20:11.547Z","ey3puyme01a9bsw","Go","2026-04-10 16:07:25.893Z",{"collectionId":17,"collectionName":18,"created":34,"created_by":13,"id":35,"name":36,"updated":37,"updated_by":13},"2026-03-04 08:20:14.253Z","ah6lvy4x8qe08l5","Golang","2026-04-10 16:07:26.172Z",{"collectionId":17,"collectionName":18,"created":39,"created_by":13,"id":40,"name":41,"updated":42,"updated_by":13},"2026-03-04 08:47:05.949Z","caufix9o52uw4bh","Real-Time Chat","2026-04-10 16:13:23.517Z",{"collectionId":17,"collectionName":18,"created":44,"created_by":13,"id":45,"name":46,"updated":47,"updated_by":13},"2026-03-04 08:48:07.088Z","brfbypclggbbkcx","WebSocket API","2026-04-10 16:13:40.594Z",{"collectionId":17,"collectionName":18,"created":49,"created_by":13,"id":50,"name":51,"updated":52,"updated_by":13},"2026-03-04 08:50:55.786Z","bn9tuj0554z99gg","Active Users","2026-04-10 16:14:30.249Z",{"collectionId":17,"collectionName":18,"created":54,"created_by":13,"id":55,"name":56,"updated":57,"updated_by":13},"2026-03-04 08:50:54.677Z","jgu82elfpwczlgf","Chat Presence","2026-04-10 16:14:29.896Z",{"collectionId":17,"collectionName":18,"created":59,"created_by":13,"id":60,"name":61,"updated":62,"updated_by":13},"2026-03-04 08:50:49.558Z","8lxakhujb04wz6u","Chat UX","2026-04-10 16:14:28.724Z",{"code":64,"collectionId":65,"collectionName":66,"created":67,"flag":68,"id":69,"is_default":70,"label":71,"updated":72},"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":74,"collectionId":75,"collectionName":76,"expand":77,"id":91,"views":92},"wqxt7ag2gn7xcmk","pbc_2105096300","school_blogs",{"category":78},{"blogIds":79,"collectionId":80,"collectionName":81,"created":82,"created_by":13,"id":74,"image":83,"image_alt":13,"image_path":84,"label":85,"name":86,"priority":87,"publish_at":88,"scheduled_at":13,"status":89,"updated":90,"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":86,"th":86},"Golang The Series",1,"2026-03-16 04:39:38.440Z","published","2026-04-25 02:32:15.470Z","hid8s1ph5iqlgp3",220,"qf7vlwj163t9xut",[20,25,30,35,40,45,50,55,60],"2025-03-24 01:51:39.476Z","Learn how to implement the Active Users feature in WebSocket Chat to allow users to see the number of users currently online in real-time.","online-users-websocket-chat","2026-04-22 07:11:42.139Z",{"en":97}]