[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blogs-th-1-1-all-go-error-handling-logging-websocket-all--*":3,"academy-blog-translations-fzamgdywui9qsn7":149},{"data":4,"page":137,"perPage":137,"totalItems":137,"totalPages":137},[5],{"alt":6,"collectionId":7,"collectionName":8,"content":9,"cover_image":10,"cover_image_path":11,"created":12,"created_by":13,"expand":14,"id":143,"keywords":144,"locale":119,"published_at":145,"scheduled_at":13,"school_blog":141,"short_description":146,"slug":147,"status":139,"title":6,"updated":148,"updated_by":13,"views":142},"Ep.24 Go กับ Error Handling & Logging บน WebSocket - เพิ่มความมั่นคงให้ระบบของคุณ!","sclblg987654321","school_blog_translations","\u003Cp class=\"p1\">\u003Cstrong>Go กับ Error Handling &amp; Logging บน WebSocket - เพิ่มความมั่นคงให้ระบบของคุณ!\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp class=\"p2\">&nbsp;\u003C\u002Fp>\u003Cp class=\"p3\">\u003Cstrong>ทำไมต้องจัดการ Error และ Logging บน WebSocket?\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp class=\"p3\">WebSocket เป็นโปรโตคอลที่ทำงานแบบเรียลไทม์ หากเกิดข้อผิดพลาด (Error) หรือการตัดการเชื่อมต่อ (Disconnection) อาจส่งผลต่อประสบการณ์ของผู้ใช้ การมีระบบจัดการ Error และ Logging จะช่วย :\u003C\u002Fp>\u003Cul class=\"ul1\">\u003Cli class=\"li3\">ตรวจสอบเหตุการณ์ผิดปกติ เช่น การเชื่อมต่อขาดหรือข้อความไม่ถูกต้อง\u003C\u002Fli>\u003Cli class=\"li3\">ดีบักปัญหาได้รวดเร็ว โดยดูข้อมูลใน Log\u003C\u002Fli>\u003Cli class=\"li3\">เพิ่มความมั่นคงของระบบ ด้วยการจัดการ Error แบบอัตโนมัติ\u003C\u002Fli>\u003C\u002Ful>\u003Cp class=\"p4\">&nbsp;\u003C\u002Fp>\u003Cp class=\"p3\">\u003Cstrong>วิธีจัดการ Error บน WebSocket\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp class=\"p3\">1. ตรวจสอบข้อผิดพลาดระหว่างการเชื่อมต่อ\u003C\u002Fp>\u003Cp class=\"p3\">ทุกครั้งที่มีการสร้างการเชื่อมต่อ WebSocket เราควรตรวจสอบ Error เพื่อให้แน่ใจว่าการเชื่อมต่อสำเร็จ\u003C\u002Fp>\u003Cp class=\"p3\">ในตัวอย่างนี้ :\u003C\u002Fp>\u003Cp class=\"p3\">หากเกิดข้อผิดพลาด จะส่งข้อความ HTTP Error กลับไปยังผู้ใช้ และบันทึก Error ลงใน Log\u003C\u002Fp>\u003Cp class=\"p3\">ตัวอย่าง :\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">conn, err := upgrader.Upgrade(w, r, nil)\r\nif err != nil {\r\n    log.Println(\"Failed to upgrade connection:\", err)\r\n    http.Error(w, \"Could not open WebSocket connection\", http.StatusBadRequest)\r\n    return\r\n}\r\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp class=\"p3\">2. จัดการ Error ขณะรับและส่งข้อความ\u003C\u002Fp>\u003Cp class=\"p3\">Error อาจเกิดขึ้นได้เมื่อไคลเอนต์ปิดการเชื่อมต่อ หรือส่งข้อความในรูปแบบที่ไม่ถูกต้อง\u003C\u002Fp>\u003Cp class=\"p3\">ในตัวอย่างนี้ :\u003C\u002Fp>\u003Cp class=\"p3\">ใช้ break เพื่อตัดการเชื่อมต่อเมื่อเกิดข้อผิดพลาด\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">for {\r\n    _, msg, err := conn.ReadMessage()\r\n    if err != nil {\r\n        log.Println(\"Error reading message:\", err)\r\n        break \u002F\u002F ปิดการเชื่อมต่อเมื่อเกิด Error\r\n    }\r\n\r\n    if err := conn.WriteMessage(websocket.TextMessage, msg); err != nil {\r\n        log.Println(\"Error writing message:\", err)\r\n        break\r\n    }\r\n}\r\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp class=\"p3\">3. ตรวจจับการตัดการเชื่อมต่อ\u003C\u002Fp>\u003Cp class=\"p3\">เมื่อไคลเอนต์ปิดการเชื่อมต่อ เราสามารถตรวจจับ Error และดำเนินการลบการเชื่อมต่อออกจากระบบได้\u003C\u002Fp>\u003Cp class=\"p3\">ตัวอย่าง :\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {\r\n    log.Printf(\"Unexpected close error: %v\", err)\r\n}\r\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp class=\"p3\">\u003Cstrong>การบันทึก Log เพื่อการตรวจสอบ\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp class=\"p3\">1. บันทึกเหตุการณ์สำคัญ\u003C\u002Fp>\u003Cp class=\"p3\">เราสามารถใช้ log.Println เพื่อบันทึกเหตุการณ์ เช่น การเชื่อมต่อใหม่ การตัดการเชื่อมต่อ และข้อความที่ส่งระหว่างเซิร์ฟเวอร์และไคลเอนต์\u003C\u002Fp>\u003Cp class=\"p3\">ตัวอย่าง :\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">log.Println(\"New client connected\")\r\ndefer log.Println(\"Client disconnected\")\r\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp class=\"p3\">2. บันทึก Log ลงไฟล์\u003C\u002Fp>\u003Cp class=\"p3\">แทนที่จะพิมพ์ Log ลงหน้าจอ เราสามารถบันทึก Log ลงไฟล์เพื่อการตรวจสอบย้อนหลัง\u003C\u002Fp>\u003Cp class=\"p3\">ตัวอย่าง :\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">file, err := os.OpenFile(\"websocket.log\", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\r\nif err != nil {\r\n    log.Fatal(err)\r\n}\r\ndefer file.Close()\r\n\r\nlog.SetOutput(file) \u002F\u002F บันทึก Log ลงไฟล์\r\nlog.Println(\"WebSocket server started\")\r\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp class=\"p3\">\u003Cstrong>ตัวอย่างการจัดการ Error และ Logging บน WebSocket\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp class=\"p3\">ในตัวอย่างนี้ :\u003C\u002Fp>\u003Cp class=\"p3\">บันทึก Log ทุกเหตุการณ์สำคัญลงไฟล์ websocket.log\u003C\u002Fp>\u003Cp class=\"p3\">ตรวจสอบและจัดการ Error ทั้งในขั้นตอนการเชื่อมต่อและระหว่างการส่งข้อความ\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext\">package main\r\n\r\nimport (\r\n    \"log\"\r\n    \"net\u002Fhttp\"\r\n    \"os\"\r\n\r\n    \"github.com\u002Fgorilla\u002Fwebsocket\"\r\n)\r\n\r\nvar upgrader = websocket.Upgrader{\r\n    CheckOrigin: func(r *http.Request) bool {\r\n        return true\r\n    },\r\n}\r\n\r\nfunc handleConnections(w http.ResponseWriter, r *http.Request) {\r\n    conn, err := upgrader.Upgrade(w, r, nil)\r\n    if err != nil {\r\n        log.Println(\"Error upgrading connection:\", err)\r\n        return\r\n    }\r\n    defer conn.Close()\r\n\r\n    log.Println(\"New client connected\")\r\n\r\n    for {\r\n        _, msg, err := conn.ReadMessage()\r\n        if err != nil {\r\n            if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {\r\n                log.Printf(\"Unexpected close error: %v\", err)\r\n            }\r\n            log.Println(\"Connection closed\")\r\n            break\r\n        }\r\n\r\n        log.Printf(\"Received message: %s\", msg)\r\n\r\n        if err := conn.WriteMessage(websocket.TextMessage, msg); err != nil {\r\n            log.Println(\"Error writing message:\", err)\r\n            break\r\n        }\r\n    }\r\n}\r\n\r\nfunc main() {\r\n    file, err := os.OpenFile(\"websocket.log\", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\r\n    if err != nil {\r\n        log.Fatal(err)\r\n    }\r\n    defer file.Close()\r\n\r\n    log.SetOutput(file)\r\n\r\n    http.HandleFunc(\"\u002Fws\", handleConnections)\r\n    log.Println(\"WebSocket server started at :8080\u002Fws\")\r\n    http.ListenAndServe(\":8080\", nil)\r\n}\r\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp class=\"p3\">\u003Cstrong>สรุปง่ายๆ\u003C\u002Fstrong>\u003C\u002Fp>\u003Cul class=\"ul1\">\u003Cli class=\"li3\">ใช้ log.Println เพื่อบันทึกเหตุการณ์สำคัญ\u003C\u002Fli>\u003Cli class=\"li3\">ตรวจสอบและจัดการ Error ในทุกขั้นตอนของ WebSocket\u003C\u002Fli>\u003Cli class=\"li3\">บันทึก Log ลงไฟล์เพื่อการตรวจสอบย้อนหลัง\u003C\u002Fli>\u003Cli class=\"li5\">ใช้\u003Cspan class=\"s2\"> websocket.IsUnexpectedCloseError \u003C\u002Fspan>เพื่อตรวจจับการตัดการเชื่อมต่อที่ไม่ปกติ\u003C\u002Fli>\u003C\u002Ful>","17_11zon_w0iqc2bydq.webp","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002Fv4zbt8hf4leh49x\u002F17_11zon_w0iqc2bydq.webp","2026-03-04 08:34:20.720Z","",{"keywords":15,"locale":113,"school_blog":123},[16,23,28,33,38,43,48,53,58,63,68,73,78,83,88,93,98,103,108],{"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:20:11.547Z","ey3puyme01a9bsw","Go","2026-04-10 16:07:25.893Z",{"collectionId":17,"collectionName":18,"created":24,"created_by":13,"id":25,"name":26,"updated":27,"updated_by":13},"2026-03-04 08:20:14.253Z","ah6lvy4x8qe08l5","Golang","2026-04-10 16:07:26.172Z",{"collectionId":17,"collectionName":18,"created":29,"created_by":13,"id":30,"name":31,"updated":32,"updated_by":13},"2026-03-04 08:33:59.518Z","7pqn3y8ffwzzde5","ภาษา Go","2026-04-10 16:08:04.777Z",{"collectionId":17,"collectionName":18,"created":34,"created_by":13,"id":35,"name":36,"updated":37,"updated_by":13},"2026-03-04 08:34:00.920Z","ecac9y661or1xka","WebSocket","2026-04-10 16:08:05.227Z",{"collectionId":17,"collectionName":18,"created":39,"created_by":13,"id":40,"name":41,"updated":42,"updated_by":13},"2026-03-04 08:24:43.639Z","mjcndls2y3h9ob6","Error Handling","2026-04-10 16:07:29.897Z",{"collectionId":17,"collectionName":18,"created":44,"created_by":13,"id":45,"name":46,"updated":47,"updated_by":13},"2026-03-04 08:33:55.302Z","0mue4zt83jcdtq9","Logging","2026-04-10 16:08:03.396Z",{"collectionId":17,"collectionName":18,"created":49,"created_by":13,"id":50,"name":51,"updated":52,"updated_by":13},"2026-03-04 08:34:15.292Z","sil8fniikll3uzb","ความมั่นคงของระบบ","2026-04-10 16:08:10.613Z",{"collectionId":17,"collectionName":18,"created":54,"created_by":13,"id":55,"name":56,"updated":57,"updated_by":13},"2026-03-04 08:32:45.519Z","dhpyn9byool9daz","การจัดการข้อผิดพลาด","2026-04-10 16:07:59.648Z",{"collectionId":17,"collectionName":18,"created":59,"created_by":13,"id":60,"name":61,"updated":62,"updated_by":13},"2026-03-04 08:34:16.471Z","hfw7yttid5e77qt","การบันทึกข้อมูล","2026-04-10 16:08:11.030Z",{"collectionId":17,"collectionName":18,"created":64,"created_by":13,"id":65,"name":66,"updated":67,"updated_by":13},"2026-03-04 08:32:27.645Z","vfe4f15x4b3afpm","การศึกษาการเขียนโปรแกรม","2026-04-10 16:07:54.538Z",{"collectionId":17,"collectionName":18,"created":69,"created_by":13,"id":70,"name":71,"updated":72,"updated_by":13},"2026-03-04 08:27:15.893Z","keubtbdqa4mblx3","การพัฒนาโปรแกรม","2026-04-10 16:07:38.769Z",{"collectionId":17,"collectionName":18,"created":74,"created_by":13,"id":75,"name":76,"updated":77,"updated_by":13},"2026-03-04 08:31:30.863Z","oyltq82epf0vqka","การเขียนโปรแกรม","2026-04-10 16:07:41.883Z",{"collectionId":17,"collectionName":18,"created":79,"created_by":13,"id":80,"name":81,"updated":82,"updated_by":13},"2026-03-04 08:34:09.187Z","3zp82zk9hqz13ko","การเขียนโปรแกรม Go","2026-04-10 16:08:08.225Z",{"collectionId":17,"collectionName":18,"created":84,"created_by":13,"id":85,"name":86,"updated":87,"updated_by":13},"2026-03-04 08:32:29.161Z","uewvwdt9cf41o8n","การเขียนโปรแกรมสำหรับมือใหม่","2026-04-10 16:07:54.935Z",{"collectionId":17,"collectionName":18,"created":89,"created_by":13,"id":90,"name":91,"updated":92,"updated_by":13},"2026-03-04 08:32:27.254Z","xl8ixz1jmfnab5f","ฝึกเขียนโปรแกรม","2026-04-10 16:07:54.377Z",{"collectionId":17,"collectionName":18,"created":94,"created_by":13,"id":95,"name":96,"updated":97,"updated_by":13},"2026-03-04 08:31:53.015Z","801w5t09mfaa9hl","ภาษาโปรแกรม","2026-04-10 16:07:46.625Z",{"collectionId":17,"collectionName":18,"created":99,"created_by":13,"id":100,"name":101,"updated":102,"updated_by":13},"2026-03-04 08:32:24.473Z","xquecx7u5svb567","โปรแกรม","2026-04-10 16:07:53.714Z",{"collectionId":17,"collectionName":18,"created":104,"created_by":13,"id":105,"name":106,"updated":107,"updated_by":13},"2026-03-04 08:26:56.612Z","yf74wkqyamfc5qx","โปรแกรมเมอร์","2026-04-10 16:07:36.426Z",{"collectionId":17,"collectionName":18,"created":109,"created_by":13,"id":110,"name":111,"updated":112,"updated_by":13},"2026-03-04 08:26:59.195Z","gab60xd583s3qaw","Superdev School","2026-04-10 16:07:37.087Z",{"code":114,"collectionId":115,"collectionName":116,"created":117,"flag":118,"id":119,"is_default":120,"label":121,"updated":122},"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":124,"collectionId":125,"collectionName":126,"expand":127,"id":141,"views":142},"wqxt7ag2gn7xcmk","pbc_2105096300","school_blogs",{"category":128},{"blogIds":129,"collectionId":130,"collectionName":131,"created":132,"created_by":13,"id":124,"image":133,"image_alt":13,"image_path":134,"label":135,"name":136,"priority":137,"publish_at":138,"scheduled_at":13,"status":139,"updated":140,"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":136,"th":136},"Golang The Series",1,"2026-03-16 04:39:38.440Z","published","2026-04-25 02:32:15.470Z","fzamgdywui9qsn7",264,"v4zbt8hf4leh49x",[20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110],"2025-01-27 04:40:43.184Z","เรียนรู้วิธีจัดการ Error และ Logging บน WebSocket เพื่อเสริมความมั่นคงและประสบการณ์ผู้ใช้ที่ดียิ่งขึ้น","go-error-handling-logging-websocket","2026-04-25 02:47:31.208Z",{"th":147}]