[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blogs-th-1-1-all-golang-websocket-realtime-status-tracking-all--*":3,"academy-blog-translations-rntmbourabwlspc":79},{"data":4,"page":67,"perPage":67,"totalItems":67,"totalPages":67},[5],{"alt":6,"collectionId":7,"collectionName":8,"content":9,"cover_image":10,"cover_image_path":11,"created":12,"created_by":13,"expand":14,"id":73,"keywords":74,"locale":49,"published_at":75,"scheduled_at":13,"school_blog":71,"short_description":76,"slug":77,"status":69,"title":6,"updated":78,"updated_by":13,"views":72},"EP.82 การใช้งาน WebSocket ในระบบติดตามสถานะ (Real-time Status Tracking)","sclblg987654321","school_blog_translations","\u003Cp>ใน EP.82 นี้เราจะพาคุณมาดูวิธีสร้างระบบติดตามสถานะแบบเรียลไทม์ (Real-time Status Tracking) ด้วย Go และ WebSocket ซึ่งเหมาะอย่างยิ่งสำหรับการ:\u003C\u002Fp>\u003Cul>\u003Cli>ติดตามสถานะของผู้ใช้\u003C\u002Fli>\u003Cli>เฝ้าระวังเซิร์ฟเวอร์\u003C\u002Fli>\u003Cli>ตรวจสอบสถานะของอุปกรณ์ IoT\u003C\u002Fli>\u003C\u002Ful>\u003Cp>ทุกการเปลี่ยนแปลงจะถูกส่งไปยังผู้ใช้ทันที โดยไม่ต้องรอ refresh หรือ polling ทำให้ระบบมี latency ต่ำ และตอบสนองแบบเรียลไทม์\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🔍 ทำไมต้องใช้ WebSocket ในระบบ Status Tracking?\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>ระบบติดตามสถานะต้อง รวดเร็ว และ ต่อเนื่อง การใช้ WebSocket ช่วยให้:\u003C\u002Fp>\u003Cul>\u003Cli>✳️ เชื่อมต่อแบบ persistent (ไม่ต้องเปิด\u002Fปิด request ใหม่ทุกครั้ง)\u003C\u002Fli>\u003Cli>✳️ ส่งข้อมูลสองทางทันที จาก server → client\u003C\u002Fli>\u003Cli>✳️ ลดการใช้ทรัพยากร เทียบกับการ polling ซ้ำ ๆ\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>✅ โครงสร้างระบบพื้นฐาน\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext language-mermaid\">graph LR\nA[Data Source&lt;br&gt;(DB, Sensor, etc.)] --&gt; B[WebSocket Server&lt;br&gt;(Golang)]\nB --&gt; C[Client&lt;br&gt;(Web\u002FMobile)]\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cul>\u003Cli>Data Source: แหล่งข้อมูลที่เปลี่ยนแปลงสถานะ\u003C\u002Fli>\u003Cli>WebSocket Server: ตรวจจับและส่งการเปลี่ยนแปลงไปยัง client\u003C\u002Fli>\u003Cli>Client: แสดงสถานะล่าสุดแบบทันที\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>📦 ตัวอย่างโค้ด WebSocket Server\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">package main\n\nimport (\n    \"log\"\n    \"net\u002Fhttp\"\n    \"time\"\n    \"github.com\u002Fgorilla\u002Fwebsocket\"\n)\n\nvar upgrader = websocket.Upgrader{\n    CheckOrigin: func(r *http.Request) bool { return true },\n}\n\ntype Client struct {\n    Conn *websocket.Conn\n    ID   string\n}\n\nvar clients = make(map[*Client]bool)\n\nfunc handleConnections(w http.ResponseWriter, r *http.Request) {\n    ws, err := upgrader.Upgrade(w, r, nil)\n    if err != nil {\n        log.Println(\"Error upgrading:\", err)\n        return\n    }\n    defer ws.Close()\n\n    client := &amp;Client{Conn: ws, ID: r.RemoteAddr}\n    clients[client] = true\n\n    log.Println(\"[+] Connected:\", client.ID)\n\n    for {\n        _, _, err := ws.ReadMessage()\n        if err != nil {\n            log.Println(\"[-] Disconnected:\", client.ID)\n            delete(clients, client)\n            break\n        }\n    }\n}\n\nfunc broadcastStatus() {\n    for {\n        statusUpdate := map[string]interface{}{\n            \"timestamp\": time.Now().Format(time.RFC3339),\n            \"status\":    \"active\",\n        }\n\n        for client := range clients {\n            err := client.Conn.WriteJSON(statusUpdate)\n            if err != nil {\n                log.Println(\"[x] Send error to\", client.ID, \":\", err)\n                client.Conn.Close()\n                delete(clients, client)\n            }\n        }\n\n        time.Sleep(5 * time.Second)\n    }\n}\n\nfunc main() {\n    http.HandleFunc(\"\u002Fws\", handleConnections)\n    go broadcastStatus()\n\n    log.Println(\"🚀 WebSocket server running on :8080\")\n    err := http.ListenAndServe(\":8080\", nil)\n    if err != nil {\n        log.Fatal(\"Server error:\", err)\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🔎 สิ่งที่โค้ดนี้ทำ:\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cfigure class=\"table\">\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>ฟังก์ชัน\u003C\u002Fth>\u003Cth>หน้าที่\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode inline=\"\">handleConnections\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>จัดการการเชื่อมต่อใหม่ เพิ่ม client เข้า map และรอ read message\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>\u003Ccode inline=\"\">broadcastStatus\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>ส่งข้อมูล JSON ไปยัง client ทุก ๆ 5 วินาที\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>\u003Ccode inline=\"\">main\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>เริ่มต้น WebSocket server และ run background task\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003C\u002Ffigure>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🧠 แนวทางปรับปรุงสำหรับ Production\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cfigure class=\"table\">\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C\u002Fth>\u003Cth>คำอธิบาย\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\u003Ctr>\u003Ctd>✅ ใช้ channel หรือ observer pattern\u003C\u002Ftd>\u003Ctd>เพื่อส่งข้อมูลทันทีเมื่อมีการเปลี่ยนแปลง แทน broadcast timer\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>✅ ใช้ Redis Pub\u002FSub หรือ Kafka\u003C\u002Ftd>\u003Ctd>สำหรับ scale หลาย instance\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>✅ Heartbeat &amp; Reconnect\u003C\u002Ftd>\u003Ctd>ตรวจจับการตัดการเชื่อมต่อและเชื่อมใหม่อัตโนมัติ\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>✅ Session management\u003C\u002Ftd>\u003Ctd>จัดการสถานะของ client, login, filter group\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003C\u002Ffigure>\u003Cp>&nbsp;\u003C\u002Fp>\u003Chr>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🚀 ท้าให้ลอง!\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cul>\u003Cli>สร้างระบบติดตามผู้ใช้หลายคนพร้อมกัน และแยกการส่งข้อมูลเฉพาะกลุ่ม\u003C\u002Fli>\u003Cli>ผูก WebSocket กับข้อมูลจากฐานข้อมูลที่เปลี่ยนแปลงแบบ real-time (เช่น Redis Stream)\u003C\u002Fli>\u003Cli>เขียน UI แสดง status dashboard สด ๆ แบบที่ใช้ใน control room หรือ admin panel\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🔜 EP ถัดไป:\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>EP.83 การใช้ WebSocket สร้างแอปพลิเคชันแบบ Collaborative\u003Cbr>เช่น ระบบแก้เอกสารพร้อมกันหลายคน, whiteboard, หรือ team chat พร้อมกันแบบเรียลไทม์\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>\u003Cstrong>อ่านบทความ Series อื่นๆ\u003C\u002Fstrong>\u003C\u002Fp>\u003Cul>\u003Cli>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.superdev.school\u002Fblogs\u002Fcategories\u002FGolang\">\u003Cstrong>Golang The Series\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.superdev.school\u002Fblogs\u002Fcategories\u002FJS2GO\">\u003Cstrong>JS2GO\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fli>\u003Cli>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.superdev.school\u002Fblogs\u002Fcategories\u002FTailwind%20CSS\">\u003Cstrong>10 Ep ที่จะให้คุณเป็นมือโปร Tailwind CSS ในชั่วข้ามคืน\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003Cstrong>🔵 Facebook: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.facebook.com\u002Fsuperdev.school.th\">\u003Cstrong>Superdev School &nbsp;(Superdev)\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003Cp>\u003Cstrong>📸 Instagram: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.instagram.com\u002Fsuperdevschool\u002F\">\u003Cstrong>superdevschool\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003Cp>\u003Cstrong>🎬 TikTok: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.tiktok.com\u002F@superdevschool\">\u003Cstrong>superdevschool\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003Cp class=\"\" data-start=\"5978\" data-end=\"6095\">\u003Cstrong>🌐 Website: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.superdev.school\u002F\">\u003Cstrong>www.superdev.school\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>","135_11zon_wd7bla7ni4.webp","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002F1put83uk52mrtb3\u002F135_11zon_wd7bla7ni4.webp","2026-03-04 08:46:57.137Z","",{"keywords":15,"locale":43,"school_blog":53},[16,23,28,33,38],{"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:34:00.920Z","ecac9y661or1xka","WebSocket","2026-04-10 16:08:05.227Z",{"collectionId":17,"collectionName":18,"created":24,"created_by":13,"id":25,"name":26,"updated":27,"updated_by":13},"2026-03-04 08:20:11.547Z","ey3puyme01a9bsw","Go","2026-04-10 16:07:25.893Z",{"collectionId":17,"collectionName":18,"created":29,"created_by":13,"id":30,"name":31,"updated":32,"updated_by":13},"2026-03-04 08:20:14.253Z","ah6lvy4x8qe08l5","Golang","2026-04-10 16:07:26.172Z",{"collectionId":17,"collectionName":18,"created":34,"created_by":13,"id":35,"name":36,"updated":37,"updated_by":13},"2026-03-04 08:46:56.766Z","gb0yfluscjvu2hq","ระบบแจ้งเตือน","2026-04-10 16:13:20.642Z",{"collectionId":17,"collectionName":18,"created":39,"created_by":13,"id":40,"name":41,"updated":42,"updated_by":13},"2026-03-04 08:44:47.893Z","1r53azecnj44o3t","Real-time","2026-04-10 16:12:50.006Z",{"code":44,"collectionId":45,"collectionName":46,"created":47,"flag":48,"id":49,"is_default":50,"label":51,"updated":52},"th","pbc_1989393366","locales","2026-01-22 10:59:55.832Z","twemoji:flag-thailand","s8wri3bt4vgg2ji",true,"Thai","2026-04-10 15:42:46.614Z",{"category":54,"collectionId":55,"collectionName":56,"expand":57,"id":71,"views":72},"wqxt7ag2gn7xcmk","pbc_2105096300","school_blogs",{"category":58},{"blogIds":59,"collectionId":60,"collectionName":61,"created":62,"created_by":13,"id":54,"image":63,"image_alt":13,"image_path":64,"label":65,"name":66,"priority":67,"publish_at":68,"scheduled_at":13,"status":69,"updated":70,"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":66,"th":66},"Golang The Series",1,"2026-03-16 04:39:38.440Z","published","2026-04-25 02:32:15.470Z","rntmbourabwlspc",219,"1put83uk52mrtb3",[20,25,30,35,40],"2025-08-29 02:32:21.040Z","เรียนรู้วิธีสร้างระบบติดตามสถานะแบบเรียลไทม์ด้วย WebSocket ในภาษา Go พร้อมตัวอย่างโค้ดเต็ม รองรับการใช้งานกับหลาย client และข้อมูลสถานะที่เปลี่ยนแปลงแบบทันที","golang-websocket-realtime-status-tracking","2026-04-25 02:48:10.573Z",{"th":77}]