Long-Polling, Websockets, เหตุการณ์ที่เซิร์ฟเวอร์ส่ง (SSE) และ Comet คืออะไร


1047

ฉันได้ลองอ่านบทความบางส่วนแล้ว แต่ฉันยังไม่ชัดเจนกับแนวคิด

มีคนต้องการจะอธิบายให้ฉันฟังว่าเทคโนโลยีเหล่านี้คืออะไร:

  1. Long Polling
  2. เหตุการณ์ที่เซิร์ฟเวอร์ส่ง
  3. WebSockets
  4. ดาวหาง

สิ่งหนึ่งที่ฉันเจอทุกครั้งคือเซิร์ฟเวอร์เปิดการเชื่อมต่อและส่งข้อมูลไปยังลูกค้า การเชื่อมต่อเปิดอย่างไรและไคลเอนต์รับข้อมูลที่ถูกพุชอย่างไร (ไคลเอนต์ใช้ข้อมูลอย่างไรบางทีรหัสบางอย่างอาจช่วยได้?)

ตอนนี้ฉันควรใช้อันใดอันหนึ่งสำหรับแอปแบบเรียลไทม์ ฉันได้ยินเกี่ยวกับ websockets เยอะมาก (กับ socket.io [a node.js library]) แต่ทำไมไม่ใช้ PHP?


1
websocket เรียลไทม์หรือ webrtc? มีไลบรารี่สำหรับ websocket ใน php คุณจำเป็นต้องเขียนโค้ดเพิ่มเติมเพื่อให้สามารถทำงานได้โดยใช้ ZMQ หรือเพียงแค่การเขียนโปรแกรมซ็อกเก็ต nodeJs ถูกสร้างขึ้นเพื่อสิ่งนี้ เหตุผลที่ websocket ไม่พร้อมใช้งานใน php คือคุณต้องรันเทอร์มินัลพิเศษและทำให้มันทำงานต่อไปเพื่อให้เซิร์ฟเวอร์ websocket พร้อมใช้งานคุณจะมีสองเซิร์ฟเวอร์ที่สำคัญที่สุด และโครงสร้าง php ไม่ใช่โครงสร้างเหตุการณ์เช่น javascript ดังนั้น websocket จึงใช้โครงสร้างเหตุการณ์เพื่อจับและส่งข้อความ
PauAI

นอกจากนี้: Comet และ ServerSent Events เป็นวิธีการแก้ปัญหาของ PHP ในการบรรลุผลตามเวลาจริง (ไม่ใช่จริง) โดยไม่ต้องสร้างเซิร์ฟเวอร์ 2 เครื่อง
PauAI

คำตอบ:


2076

ในตัวอย่างด้านล่างไคลเอ็นต์คือเบราว์เซอร์และเซิร์ฟเวอร์เป็นเว็บเซิร์ฟเวอร์ที่โฮสต์เว็บไซต์

ก่อนที่คุณจะสามารถเข้าใจเทคโนโลยีเหล่านี้คุณต้องเข้าใจการเข้าชมเว็บ HTTP แบบคลาสสิกก่อน

HTTP ปกติ:

  1. ลูกค้าร้องขอหน้าเว็บจากเซิร์ฟเวอร์
  2. เซิร์ฟเวอร์จะคำนวณการตอบสนอง
  3. เซิร์ฟเวอร์ส่งการตอบสนองไปยังลูกค้า

HTTP

Ajax Polling:

  1. ลูกค้าร้องขอหน้าเว็บจากเซิร์ฟเวอร์โดยใช้ HTTP ปกติ (ดู HTTP ด้านบน)
  2. ลูกค้าได้รับหน้าเว็บที่ร้องขอและเรียกใช้ JavaScript บนหน้าเว็บที่ร้องขอไฟล์จากเซิร์ฟเวอร์ในช่วงเวลาปกติ (เช่น 0.5 วินาที)
  3. เซิร์ฟเวอร์จะคำนวณการตอบกลับแต่ละครั้งและส่งกลับเช่นเดียวกับการรับส่งข้อมูล HTTP ปกติ

Ajax Polling

Ajax Long-Polling:

  1. ลูกค้าร้องขอหน้าเว็บจากเซิร์ฟเวอร์โดยใช้ HTTP ปกติ (ดู HTTP ด้านบน)
  2. ลูกค้าได้รับหน้าเว็บที่ร้องขอและเรียกใช้งาน JavaScript บนหน้าเว็บที่ร้องขอไฟล์จากเซิร์ฟเวอร์
  3. เซิร์ฟเวอร์ไม่ตอบสนองทันทีกับข้อมูลที่ร้องขอ แต่รอจนกว่าจะมีข้อมูลใหม่
  4. เมื่อมีข้อมูลใหม่เซิร์ฟเวอร์จะตอบกลับด้วยข้อมูลใหม่
  5. ลูกค้าได้รับข้อมูลใหม่และส่งคำขออื่นไปยังเซิร์ฟเวอร์ทันทีเพื่อเริ่มกระบวนการใหม่

Ajax Long-Polling

เหตุการณ์ที่ส่งเซิร์ฟเวอร์ HTML5 (SSE) / EventSource:

  1. ลูกค้าร้องขอหน้าเว็บจากเซิร์ฟเวอร์โดยใช้ HTTP ปกติ (ดู HTTP ด้านบน)
  2. ลูกค้าได้รับหน้าเว็บที่ร้องขอและเรียกใช้งาน JavaScript บนหน้าเว็บที่เปิดการเชื่อมต่อกับเซิร์ฟเวอร์
  3. เซิร์ฟเวอร์ส่งกิจกรรมไปยังลูกค้าเมื่อมีข้อมูลใหม่ให้

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

HTML5 SSE

HTML5 Websockets:

  1. ลูกค้าร้องขอหน้าเว็บจากเซิร์ฟเวอร์โดยใช้ http ปกติ (ดู HTTP ด้านบน)
  2. ลูกค้าได้รับหน้าเว็บที่ร้องขอและเรียกใช้งาน JavaScript บนหน้าเว็บที่เปิดการเชื่อมต่อกับเซิร์ฟเวอร์
  3. เซิร์ฟเวอร์และไคลเอนต์สามารถส่งข้อความซึ่งกันและกันเมื่อข้อมูลใหม่ (ทั้งสองด้าน) พร้อมใช้งาน

    • การรับส่งข้อมูลแบบเรียลไทม์จากเซิร์ฟเวอร์ไปยังไคลเอนต์และจากไคลเอนต์ไปยังเซิร์ฟเวอร์
    • คุณจะต้องการใช้เซิร์ฟเวอร์ที่มีการวนรอบเหตุการณ์
    • ด้วย WebSockets คุณสามารถเชื่อมต่อกับเซิร์ฟเวอร์จากโดเมนอื่นได้
    • นอกจากนี้ยังเป็นไปได้ที่จะใช้บุคคลที่สามโฮสต์เซิร์ฟเวอร์ WebSocket เช่นPusherหรือคนอื่น ๆ วิธีนี้คุณจะต้องใช้งานฝั่งไคลเอ็นต์ซึ่งง่ายมาก!
    • หากคุณต้องการอ่านเพิ่มเติมฉันพบว่ามีประโยชน์มาก: ( บทความ ), (บทความ) ( บทช่วยสอน )

HTML5 WebSockets

ดาวหาง:

Comet คือชุดของเทคนิคก่อน HTML5 ซึ่งใช้การสตรีมและการโพลแบบยาวเพื่อให้ได้แอปพลิเคชันแบบเรียลไทม์ อ่านเพิ่มเติมเกี่ยวกับวิกิพีเดียหรือนี้บทความ


ตอนนี้ฉันควรใช้อันใดอันหนึ่งสำหรับแอปเรียลไทม์ (ที่ฉันต้องการรหัส) ฉันได้ยินเกี่ยวกับ websockets เยอะมาก (กับ socket.io [a node.js library]) แต่ทำไมไม่ใช้ PHP?

คุณสามารถใช้ PHP กับ WebSockets ตรวจสอบวงล้อ


21
นี่มันเจ๋งมาก! ฉันอ่าน SSE และพบบทความนี้มันดีมาก - เหมือนตอนนี้ฉันได้เปรียบเทียบสิ่งต่าง ๆ คุณสามารถรวม SSE ที่นี่เพื่อให้เราสามารถตรวจสอบความแตกต่างกับ Websocket ได้หรือไม่
ดัชนี

1
@ Tieme โอ้เป็นอย่างนั้นเหรอ? ฉันคิดว่า SSE หมายถึงเหตุการณ์ที่เซิร์ฟเวอร์ส่ง อย่างไรก็ตามขอบคุณฉันเห็นมันตอนนี้
ดัชนี

1
ถาม: ใน php สมมติว่าคุณใช้ websocket ลูกค้าทุกคนที่เชื่อมต่อกับเซิร์ฟเวอร์ของฉันโดยใช้ ws: จะมีหนึ่งเธรดที่จัดสรรให้กับเขา / เธอและขนาดของมันจะอยู่ที่ ~ 2mb ตามคำขอปกติหรือไม่? สิ่งนั้นจะแตกต่างกันใน nodejs อย่างไร จำนวนไคลเอ็นต์ที่เกิดขึ้นพร้อมกันสามารถ nodejs จัดการและเมื่อมันแบ่งสิ่งที่เกิดขึ้น?
มูฮัมหมัดอูเมอ

5
คุณสามารถทำสิ่งเดียวกันทั้งสองวิธีได้ แต่กลไกนั้นแตกต่างกัน Long-polling ใช้ข้อมูล http 'ปกติ' SSE ใช้โปรโตคอลพื้นฐานที่แตกต่างกันและต้องการการตั้งค่าเซิร์ฟเวอร์ที่แตกต่างกันเมื่อเปรียบเทียบกับ Long-polling
Tieme

2
คุณสามารถใช้ Apache ได้ถ้าต้องการ แต่ผู้คนจำนวนมากใช้ Node.js เพราะมันมีการวนรอบเหตุการณ์ แต่สำหรับ Apache ดูstackoverflow.com/questions/12203443/…
Tieme

37

Tieme ใช้ความพยายามอย่างมากในการตอบคำถามที่ยอดเยี่ยมของเขา แต่ฉันคิดว่าประเด็นหลักของคำถาม OPs คือเทคโนโลยีเหล่านี้เกี่ยวข้องกับ PHP มากกว่าการทำงานของแต่ละเทคโนโลยีอย่างไร

PHP เป็นภาษาที่ใช้มากที่สุดในการพัฒนาเว็บนอกเหนือจาก html, css และ javascript PHP มี 2 ประเด็นที่สำคัญเมื่อพูดถึงแอปพลิเคชั่นตามเวลาจริง:

1) PHP เริ่มเป็น CGI ขั้นพื้นฐานมาก PHP มีความก้าวหน้าไปไกลมากตั้งแต่ยังอยู่ในช่วงเริ่มต้น แต่มันก็เกิดขึ้นเพียงไม่กี่ก้าว PHP มีผู้ใช้หลายล้านคนในเวลานั้นมันกลายเป็นไลบรารี C ที่สามารถฝังตัวและยืดหยุ่นได้ซึ่งทุกวันนี้ส่วนใหญ่ขึ้นอยู่กับรูปแบบการเรียกใช้ก่อนหน้านี้ดังนั้นจึงยังไม่พยายามที่จะหลบหนี โมเดล CGI ภายใน แม้แต่อินเตอร์เฟสบรรทัดคำสั่งจะเรียกใช้ไลบรารี PHP (libphp5.so บน linux, php5ts.dll บน windows และอื่น ๆ ) ราวกับว่ามันยังคงเป็น cgi ที่ประมวลผลคำขอ GET / POST มันยังคงรันโค้ดราวกับว่ามันเพิ่งจะสร้าง "หน้า" แล้วจบมันเป็นวงจรชีวิต เป็นผลให้มันมีการสนับสนุนน้อยมากสำหรับการเขียนโปรแกรมแบบมัลติเธรดหรือเหตุการณ์ที่ขับเคลื่อนด้วย (ภายในผู้ใช้ PHP) ทำให้ในปัจจุบันไม่ได้ใช้งานจริงสำหรับการใช้งานแบบหลายผู้ใช้

โปรดทราบว่า PHP มีส่วนขยายเพื่อให้ลูปเหตุการณ์ (เช่น libevent) และเธรด (เช่น pthreads) ใน PHP userspace แต่แอปพลิเคชั่นที่ใช้งานน้อยมาก

2) PHP ยังคงมีปัญหาสำคัญกับการเก็บขยะ แม้ว่าปัญหาเหล่านี้จะได้รับการปรับปรุงอย่างต่อเนื่อง (น่าจะเป็นขั้นตอนที่ดีที่สุดในการสิ้นสุดวงจรชีวิตตามที่อธิบายไว้ข้างต้น) แม้ความพยายามที่ดีที่สุดในการสร้างแอปพลิเคชัน PHP ที่ใช้งานระยะยาว สิ่งนี้ยังทำให้ไม่สามารถใช้งานได้ตามเวลาจริง

PHP 7 จะเป็นขั้นตอนที่ยอดเยี่ยมในการแก้ไขปัญหาเหล่านี้เช่นกันและดูเหมือนว่าจะเป็นแพลตฟอร์มสำหรับแอปพลิเคชันแบบเรียลไทม์


2
การแก้ไขเล็ก ๆ น้อย ๆ อย่างหนึ่ง: PHP เขียนด้วยภาษา C เสมอสามารถดูได้ที่นี่: museum.php.net/php1นอกจากนี้ "การใช้งานที่น้อยกว่า (แต่ได้รับความนิยมอย่างมาก)" ค่อนข้างขัดแย้งกันเอง บางทีสิ่งที่คุณหมายถึงคือ "ทันสมัยมากขึ้น"?
IMSoP

@IMSoP - ขอบคุณสำหรับการแก้ไขฉันได้ใช้ PHP มานานกว่าทศวรรษและได้รับเสมอภายใต้ความประทับใจที่มีรากอยู่ใน Perl หน้าประวัติ PHP สนับสนุนอย่างชัดเจนว่าเป็น C เช่นกัน ฉันจะแก้ไขคำตอบของฉันเมื่อฉันค้นหาสักครู่
JSON

ฉันจะลบบิตเกี่ยวกับ Perl เนื่องจากมันไม่เข้ากันกับเอกสารอย่างเป็นทางการ แต่นี่ก็ยังเป็นพื้นที่ที่สับสนในการพัฒนาต้นของ PHP
JSON

PHP 7 ดูเหมือนว่าจะเป็นแพลตฟอร์มสำหรับการใช้งานแบบเรียลไทม์? การปรับปรุง / เปลี่ยนแปลง PHP7 สำหรับแอปพลิเคชั่นตามเวลาจริงคืออะไร?
ฉันจะกลับมา


9

ฉันได้พยายามที่จะทำให้ทราบเกี่ยวกับเหล่านี้และมีการเก็บรวบรวมและการเขียนตัวอย่างจากมุมมองของ Java

HTTP สำหรับนักพัฒนา Java

Reverse Ajax - แบบเก่า

การจัดการ Async บนฝั่งเซิร์ฟเวอร์

Reverse Ajax - รูปแบบใหม่

เหตุการณ์ที่เซิร์ฟเวอร์ส่ง

วางไว้ที่นี่สำหรับผู้พัฒนาจาวาที่กำลังมองหาหัวข้อเดียวกัน


ไซต์เหล่านี้ส่วนใหญ่ไม่ทำงาน!
Alexander Dunn

@AlexanderDunn ขอบคุณที่นำมันขึ้นมา ฉันจะแก้ไขด้วยลิงก์ที่อัปเดตแล้ว
John

1

คุณสามารถใช้ Node.JS ในเว็บแอปของคุณเพื่อการสื่อสารแบบเรียลไทม์เท่านั้น Node.JS นั้นทรงพลังจริงๆเมื่อพูดถึง WebSockets ดังนั้น "การแจ้งเตือน PHP ผ่าน Node.js" จึงเป็นแนวคิดที่ดี

ดูตัวอย่างนี้: การสร้างแอปแชทตามเวลาจริงด้วย PHP และ Node.js

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.