ข้ามไปยังเนื้อหา

WebSocket เทียบกับ HTTP, Polling และ SSE

WebSocket ไม่ใช่วิธีเดียวในการย้ายข้อมูลระหว่างเบราว์เซอร์กับ server และไม่ใช่วิธีที่ถูกต้องเสมอไปด้วย จะเลือกได้ดีก็ต้องรู้จักทางเลือกอื่นก่อน บทเรียนนี้จะพาเดินผ่านอีกสี่แนวทางแล้ววางเรียงเทียบกับ WebSocket บนสองแกนที่สำคัญที่สุด: latency (client รู้เรื่องเหตุการณ์ฝั่ง server เร็วแค่ไหน) และ overhead (เสียงานเปล่ามากแค่ไหนต่อ message ที่มีประโยชน์หนึ่งตัว)

เส้นฐาน client ถาม server ตอบ การแลกเปลี่ยนจบลง server ไม่มีทาง พูดก่อนได้ สำหรับการดึงหน้าและส่งฟอร์ม แบบนี้สมบูรณ์แบบ แต่ถ้าอยากรู้เรื่องเหตุการณ์ที่เกิดบน server ก็แทบไม่ช่วยอะไรเลย — client ต้องกลับไปถามใหม่ ซึ่งพาเราไปสู่ polling

client ถามว่า “มีอะไรใหม่ไหม?” ตามตัวจับเวลาคงที่ — สมมติทุกไม่กี่วินาที — และ server ตอบทันที โดยส่วนใหญ่ตอบว่า “ไม่มี” เป็นเวลาส่วนใหญ่

sequenceDiagram
  participant C as Client
  participant S as Server
  loop every few seconds
    C->>S: GET /updates
    S-->>C: 200 (nothing new)
  end
  Note over S: event happens here
  C->>S: GET /updates
  S-->>C: 200 (here is the update)
Short polling: request ซ้ำ ๆ คำตอบส่วนใหญ่ว่างเปล่า

Latency ถูกจำกัดด้วยช่วงเวลาของคุณ — เหตุการณ์หนึ่งอาจนั่งรออยู่โดยไม่มีใครเห็นได้นานถึงหนึ่งรอบ polling Overhead สูง: request ส่วนใหญ่แบก HTTP header เต็ม ๆ แต่ได้อะไรที่ไม่มีประโยชน์กลับมา กระชับช่วงเวลาให้ถี่ขึ้นก็ตัด latency ลงได้ แต่ request ที่สูญเปล่าก็เพิ่มเป็นทวีคูณ ข้อดีจริง ๆ ข้อเดียวคือเรียบง่ายและทำงานได้ทุกที่

ตัวแปรที่ฉลาดกว่า client ส่ง request ไป แล้ว server ถือค้างไว้ จนกว่าจะมีเหตุการณ์เกิดขึ้นหรือครบ timeout ค่อยตอบกลับ จากนั้น client ก็ยิง request อันใหม่ทันทีแล้วรอต่อ

วิธีนี้ดัน latency ลงใกล้เคียงเรียลไทม์ — response มาทันทีที่เหตุการณ์มา — โดยไม่ต้องมีตัวจับเวลาที่วุ่นวาย แต่ทุก message ที่ส่งได้ก็ยังจ่ายเต็มเป็นหนึ่งรอบ request/response บวกการเชื่อมต่อใหม่ พออัตราเหตุการณ์หนักขึ้น overhead จึงไต่สูงตาม และไปบีบขีดจำกัดจำนวนการเชื่อมต่อของ server ได้

SSE เปิดการเชื่อมต่อ HTTP ที่มีอายุยาว เส้นเดียว ซึ่ง server จะ stream เหตุการณ์ไปยัง client ทันทีที่เกิดขึ้น วิธีนี้มีประสิทธิภาพ เชื่อมต่อใหม่ให้อัตโนมัติ และวิ่งบน HTTP ธรรมดา แต่ออกแบบมาให้เป็น ทางเดียว: server → client เท่านั้น client ส่งข้อมูลกลับผ่านช่องเดิมไม่ได้ ถ้าจะคุยกับ server ต้องยิง HTTP request ธรรมดาแยกต่างหาก

WebSocket ก็เปิดการเชื่อมต่อเส้นเดียวค้างไว้เหมือนกัน แต่เป็นแบบ สองทิศทาง: หลัง handshake ทั้งสองฝ่าย push message ได้อย่างอิสระด้วย overhead ต่อ message ที่น้อยที่สุด latency ต่ำเท่าที่เครือข่ายจะยอมให้ได้ใน ทั้งสอง ทิศทาง และไม่มีภาษี header ต่อ message

แนวทางทิศทางLatency ถึง clientOverhead ต่อข้อความเหมาะที่สุดเมื่อ
HTTP request/responseclient → server (ครั้งเดียว)N/A (ไม่มี push)หนึ่งรอบเต็มต่อ requestหน้าเพจ ฟอร์ม API ธรรมดา
Short pollingclient ถามซ้ำ ๆสูงสุดหนึ่งช่วงเวลาสูง (ส่วนใหญ่ว่างเปล่า)การตรวจสอบเล็กน้อยเป็นครั้งคราว
Long pollingclient ถาม server ถือไว้เกือบเรียลไทม์หนึ่งรอบต่อเหตุการณ์กึ่งเรียลไทม์บน HTTP ธรรมดา
SSEserver → client เท่านั้นเกือบเรียลไทม์ต่ำ (หนึ่งสตรีม)server push ไม่มี uplink จาก client
WebSocketทั้งสองทิศทางต่ำที่สุด ทั้งสองทางต่ำที่สุด (ข้อความแบบ framed)เรียลไทม์แบบโต้ตอบสองทาง
  • ถ้า client เพียงแค่ อ่าน สตรีมของเหตุการณ์จาก server เท่านั้น — ฟีดข่าว, การ tail log สด, อัปเดตความคืบหน้า — SSE เรียบง่ายกว่าและวิ่งบนโครงสร้างพื้นฐาน HTTP ธรรมดา
  • ถ้าทั้งสองฝ่ายต้องส่งบ่อย ๆ และโต้ตอบกัน — แชต, การทำงานร่วมกัน, เกม, การควบคุมแบบสด — WebSocket คือตัวเลือกที่เป็นธรรมชาติ
  • ถ้าคุณต้องการบางอย่างวันนี้บนโครงสร้างพื้นฐานที่พื้นฐานที่สุดและทราฟฟิกเบา long polling เป็นทางออกชั่วคราวที่สมเหตุสมผล ส่วน short polling ใช้เฉพาะกรณีที่เล็กน้อยจริง ๆ เท่านั้น

ใช้ WebSocket สำหรับ Low-Frequency Updates อาการ:

  • data อัปเดตทุก 30 วินาที แต่ใช้ WebSocket
  • เพิ่ม complexity โดยไม่จำเป็น — HTTP polling ทุก 30 วิก็เพียงพอ
  • ประเมิน update frequency ก่อนเลือก technology

ใช้ Long Polling สำหรับ High-Frequency Events อาการ:

  • ส่ง event 100 ครั้งต่อวินาที ผ่าน long polling
  • เปิด HTTP connection ใหม่ 100 ครั้งต่อวินาที — ทำลาย server
  • เปลี่ยนไปใช้ WebSocket เมื่อ event rate สูงกว่า 1-2 ครั้งต่อวินาที

💡 ตัวอย่างจากของจริง

Twitter/X:

  • ใช้ SSE สำหรับ notification และ timeline update (server → client only)
  • WebSocket สำหรับ DM real-time chat (bidirectional)

Intercom:

  • เริ่มจาก long polling สำหรับ chat widget
  • migrate ไป WebSocket เมื่อ user load เพิ่มขึ้น — ลด server connection overhead 80%
อะไรคือข้อจำกัดสำคัญของ Server-Sent Events เมื่อเทียบกับ WebSocket?
ทำไม short polling ถึงมีแนวโน้มที่จะมี overhead สูง?
คุณกำลังสร้างไวต์บอร์ดร่วมกันแบบโต้ตอบที่ผู้ใช้ทุกคนทั้งส่งและรับการแก้ไขอย่างต่อเนื่อง อันไหนเหมาะที่สุด?
long polling ลด latency เมื่อเทียบกับ short polling ได้อย่างไร?