ระบบ Live Chat ง่ายๆ เกือบทำให้การ Release ครั้งนี้พังพินาศ

ระบบ Live Chat พื้นฐานเกือบจะทำลายการ Release ล่าสุดของผม

ฟังดูเหมือนง่าย แค่แสดงผู้ใช้ที่อยู่ใกล้เคียงและให้พวกเขาคุยกันได้ แต่ในความเป็นจริงทางเทคนิคนั้นยากกว่ามาก ผมต้องเชื่อมต่อ Live Chat เข้ากับระบบ Geolocation และระบบให้คะแนน (Rating system) ซึ่งทำให้เกิดความซับซ้อนมหาศาลอยู่เบื้องหลัง

สถาปัตยกรรม (The Architecture):

• Frontend: React และ TypeScript • Backend: Node.js พร้อมด้วย Express และ WebSockets • Database: PostgreSQL สำหรับข้อมูลผู้ใช้และคะแนน • Cache: Redis สำหรับ active sessions และ presence

ปัญหาเรื่อง Geolocation

การจับคู่ผู้ใช้ตามตำแหน่งที่ตั้งไม่ใช่เรื่องง่าย ผมต้องจัดการกับ edge cases มากมาย:

  • การจัดเก็บค่า latitude และ longitude
  • การใช้ Postgres extensions เพื่อ query ระยะทาง
  • การจัดการกับผู้ใช้ที่ปฏิเสธการอนุญาตเข้าถึงตำแหน่ง
  • การจัดการข้อมูลที่ล้าสมัย (stale data) เมื่อผู้ใช้เคลื่อนที่โดยไม่ได้เปิดแอป

ถ้าผมต้องทำสิ่งนี้อีกครั้ง ผมจะแยกส่วนการเก็บข้อมูลตำแหน่งออกจากส่วนการจับคู่ (matching) โดยใช้บริการ (services) ที่ต่างกัน

ความเป็นจริงของ Live Chat

WebSockets ช่วยให้มีฟีเจอร์แบบ real-time แต่ก็มาพร้อมกับความวุ่นวายด้วย ผมใช้ Redis pub/sub เพื่อส่งข้อความข้ามเซิร์ฟเวอร์ต่างๆ

ส่วนที่ยากที่สุดคือ:

  • การเคลียร์การเชื่อมต่อ (connections) เมื่อผู้ใช้ตัดการเชื่อมต่ออย่างไม่คาดคิด
  • การป้องกันไม่ให้ส่งข้อความไปยังห้องที่ผู้ใช้กดออกจากไปแล้ว
  • การจัดการการเชื่อมต่อใหม่ (reconnects) โดยไม่ทำให้เกิด ghost sessions

ผมเรียนรู้ว่าการใช้ formal state machine นั้นดีกว่าการใช้ flag ง่ายๆ

ระบบการให้คะแนน (The Rating System)

การให้คะแนนดูเหมือนเป็นเรื่องเล็กน้อยจนกว่าคุณจะได้สร้างมันขึ้นมาจริงๆ ผมต้องทำให้มั่นใจว่า:

  • ผู้ใช้ไม่สามารถให้คะแนนเซสชันเดิมซ้ำสองครั้งได้
  • คะแนนต้องถูกรวบรวม (aggregate) อย่างรวดเร็วสำหรับการแสดงผลในหน้าโปรไฟล์
  • ข้อมูลต้องมีความสอดคล้องกัน (consistent) ทั่วทั้งแอป

ผมใช้ unique constraints บน session IDs เพื่อป้องกันข้อมูลซ้ำ และทำ caching ค่าเฉลี่ยเพื่อรักษาประสิทธิภาพ (performance)

บทเรียนที่ได้รับ

ถ้าผมต้องสร้างสิ่งนี้ใหม่ในวันนี้ ผมจะเปลี่ยน 3 อย่าง:

  1. แยกการจับคู่ (matching) และการแชท (chat) ออกเป็นโมดูลที่แยกจากกัน
  2. ใช้การทำ modeling ที่ชัดเจนสำหรับสถานะการเชื่อมต่อ WebSocket
  3. เพิ่ม logs และ metrics ที่ดีกว่าเดิมสำหรับการแชทและการจับคู่ตั้งแต่วันแรก

การสร้างซอฟต์แวร์คือชุดของการตัดสินใจเล็กๆ น้อยๆ ซึ่งการตัดสินใจเหล่านี้จะเป็นตัวกำหนดว่าระบบของคุณจะสะอาด (clean) หรือเปราะบาง (brittle)

คุณเคยสร้างระบบ Live Chat หรือระบบจับคู่บ้างไหม? ถ้าเป็นคุณ คุณจะทำอะไรให้ต่างออกไป?

Source: https://dev.to/jaeger974/simple-live-chat-almost-sank-this-release-2pn7