AJAX จะใช้ความยาว / การลงคะแนนสั้นสั้นใน HTML5 WebSockets ได้อย่างไร


306

ฉันกำลังสร้างแอปพลิเคชั่นแชทเล็ก ๆ สำหรับเพื่อน ๆ แต่ไม่แน่ใจเกี่ยวกับวิธีรับข้อมูลในเวลาที่ไม่เป็นคู่มือหรือเป็นพื้นฐานในการบังคับให้รีเฟรชหน้าเว็บ

ขณะนี้ฉันกำลังใช้สิ่งนี้โดยใช้ AJAX แบบง่าย ๆ แต่สิ่งนี้มีข้อเสียของการกดปุ่มเซิร์ฟเวอร์เป็นประจำเมื่อเวลาผ่านไปสั้น ๆ

ในการค้นคว้าการทำโพลแบบยาว / สั้นฉันใช้ HTML5 WebSockets นี้ดูเหมือนง่ายต่อการใช้ แต่ผมไม่แน่ใจว่าถ้ามีข้อเสียบางอย่างซ่อนอยู่ ตัวอย่างเช่นฉันคิดว่า WebSockets รองรับเฉพาะเบราว์เซอร์บางตัวเท่านั้น มีข้อเสียอื่น ๆ สำหรับ WebSockets ที่ฉันควรระวังหรือไม่?

เนื่องจากดูเหมือนว่าทั้งสองเทคโนโลยีจะทำสิ่งเดียวกันสถานการณ์แบบใดที่เราจะเลือกใช้อีกแบบหนึ่ง โดยเฉพาะอย่างยิ่ง HTML5 WebSockets ทำให้การสำรวจ AJAX ยาว / สั้นล้าสมัยหรือมีเหตุผลที่น่าสนใจที่จะชอบ AJAX มากกว่า WebSockets หรือไม่

คำตอบ:


508

WebSockets คืออนาคตที่แน่นอน

การทำโพลแบบยาวเป็นวิธีการที่สกปรกเพื่อป้องกันการสร้างการเชื่อมต่อสำหรับแต่ละคำขอเช่น AJAX แต่การทำโพลแบบยาวนั้นถูกสร้างขึ้นเมื่อไม่มี WebSockets ขณะนี้เนื่องจาก WebSockets การสำรวจระยะยาวกำลังจะหายไป

WebRTC อนุญาตสำหรับการสื่อสารแบบเพียร์ทูเพียร์

ผมขอแนะนำให้เรียนรู้WebSockets

เปรียบเทียบ:

เทคนิคการสื่อสารที่แตกต่างกันบนเว็บ

  • AJAX - →request responseสร้างการเชื่อมต่อกับเซิร์ฟเวอร์ส่งส่วนหัวคำขอพร้อมข้อมูลเสริมรับการตอบกลับจากเซิร์ฟเวอร์และปิดการเชื่อมต่อ รองรับเบราว์เซอร์ที่สำคัญทั้งหมด

  • โพลสำรวจความยาว - request→การ→การwait responseสร้างการเชื่อมต่อกับเซิร์ฟเวอร์อย่างที่ AJAX ทำ แต่รักษาการเชื่อมต่อแบบเปิดไว้ตลอดเวลา (ไม่นาน) ระหว่างการเชื่อมต่อไคลเอ็นต์ที่เปิดสามารถรับข้อมูลจากเซิร์ฟเวอร์ ไคลเอนต์ต้องเชื่อมต่อเป็นระยะหลังจากการเชื่อมต่อถูกปิดเนื่องจากการหมดเวลาหรือข้อมูล ในฝั่งเซิร์ฟเวอร์นั้นยังคงเป็นเหมือนคำขอ HTTP เช่นเดียวกับ AJAX ยกเว้นคำตอบตามคำขอจะเกิดขึ้นในขณะนี้หรือบางเวลาในอนาคตที่กำหนดโดยตรรกะของแอปพลิเคชัน แผนภูมิการสนับสนุน (เต็ม) | วิกิพีเดีย

  • WebSockets - ↔client serverสร้างการเชื่อมต่อ TCP ไปยังเซิร์ฟเวอร์และเปิดไว้นานเท่าที่ต้องการ เซิร์ฟเวอร์หรือไคลเอนต์สามารถปิดการเชื่อมต่อได้อย่างง่ายดาย ไคลเอนต์ต้องผ่านกระบวนการจับมือ HTTP ที่เข้ากันได้ หากทำได้สำเร็จเซิร์ฟเวอร์และไคลเอ็นต์สามารถแลกเปลี่ยนข้อมูลในทั้งสองทิศทางได้ตลอดเวลา จะมีประสิทธิภาพหากแอปพลิเคชันต้องการการแลกเปลี่ยนข้อมูลบ่อยครั้ง WebSockets มีการทำ data data ซึ่งรวมถึงการปิดบังสำหรับแต่ละข้อความที่ส่งจากไคลเอ็นต์ไปยังเซิร์ฟเวอร์ดังนั้นข้อมูลจึงถูกเข้ารหัส แผนภูมิสนับสนุน (ดีมาก) | วิกิพีเดีย

  • WebRTC - ↔peer peerขนส่งเพื่อสร้างการสื่อสารระหว่างลูกค้าและเป็นผู้ขนส่งที่ไม่เชื่อเรื่องพระเจ้าดังนั้นจึงสามารถใช้ UDP, TCP หรือเลเยอร์นามธรรมได้มากขึ้น โดยทั่วไปจะใช้สำหรับการถ่ายโอนข้อมูลปริมาณมากเช่นการสตรีมวิดีโอ / เสียงที่ความน่าเชื่อถือเป็นรองและไม่กี่เฟรมหรือการลดลงของความก้าวหน้าด้านคุณภาพสามารถเสียสละในเวลาตอบสนองและอย่างน้อยการถ่ายโอนข้อมูลบางอย่าง ทั้งสองด้าน (เพื่อนร่วมงาน) สามารถส่งข้อมูลให้กันและกันได้อย่างอิสระ แม้ว่าจะสามารถใช้งานได้อย่างอิสระโดยสิ้นเชิงจากเซิร์ฟเวอร์รวมศูนย์ แต่ก็ยังต้องการวิธีการแลกเปลี่ยนข้อมูลจุดปลายซึ่งในกรณีส่วนใหญ่ผู้พัฒนายังคงใช้เซิร์ฟเวอร์ส่วนกลางเพื่อเชื่อมโยง "เพื่อน" สิ่งนี้จำเป็นสำหรับการแลกเปลี่ยนข้อมูลที่จำเป็นสำหรับการสร้างการเชื่อมต่อหลังจากนั้นไม่จำเป็นต้องใช้เซิร์ฟเวอร์ส่วนกลาง แผนภูมิการสนับสนุน (กลาง) | วิกิพีเดีย

  • เซิร์ฟเวอร์ส่งเหตุการณ์ - ←client serverลูกค้าสร้างการเชื่อมต่อกับเซิร์ฟเวอร์แบบถาวรและระยะยาว มีเพียงเซิร์ฟเวอร์เท่านั้นที่สามารถส่งข้อมูลไปยังลูกค้าได้ หากลูกค้าต้องการส่งข้อมูลไปยังเซิร์ฟเวอร์ก็จะต้องใช้เทคโนโลยี / โปรโตคอลอื่นให้ทำเช่นนั้น โปรโตคอลนี้เข้ากันได้กับ HTTP และใช้งานง่ายในแพลตฟอร์มฝั่งเซิร์ฟเวอร์ส่วนใหญ่ นี่เป็นโปรโตคอลที่นิยมใช้มากกว่าการใช้ Long Polling สนับสนุนแผนภูมิ (ดียกเว้น IE) | วิกิพีเดีย

ข้อดี:

ข้อได้เปรียบหลักของฝั่งเซิร์ฟเวอร์WebSocketsคือไม่ใช่คำขอ HTTP (หลังจากจับมือกัน) แต่เป็นโปรโตคอลการสื่อสารที่ใช้ข้อความที่เหมาะสม สิ่งนี้ช่วยให้คุณบรรลุผลการดำเนินงานและข้อได้เปรียบทางสถาปัตยกรรมที่ยิ่งใหญ่ ตัวอย่างเช่นใน node.js คุณสามารถแบ่งปันหน่วยความจำเดียวกันสำหรับการเชื่อมต่อซ็อกเก็ตที่แตกต่างกันดังนั้นพวกเขาจึงสามารถเข้าถึงตัวแปรที่แชร์กันได้ ดังนั้นคุณไม่จำเป็นต้องใช้ฐานข้อมูลเป็นจุดแลกเปลี่ยนตรงกลาง (เช่น AJAX หรือ Long Polling ด้วยภาษาเช่น PHP) คุณสามารถจัดเก็บข้อมูลใน RAM หรือเผยแพร่ระหว่างซ็อกเก็ตได้ทันที

ข้อควรพิจารณาด้านความปลอดภัย

ผู้คนมักจะกังวลเกี่ยวกับความปลอดภัยของ WebSockets ความจริงก็คือมันสร้างความแตกต่างเพียงเล็กน้อยหรือทำให้ WebSockets เป็นตัวเลือกที่ดีกว่า ก่อนอื่นด้วย AJAX มีโอกาสสูงที่MITMเนื่องจากการร้องขอแต่ละครั้งเป็นการเชื่อมต่อ TCP ใหม่ที่ผ่านโครงสร้างพื้นฐานอินเทอร์เน็ต ด้วย WebSockets เมื่อเชื่อมต่อแล้วจะมีความท้าทายในการสกัดกั้นระหว่างกันมากขึ้นโดยมีการปิดเฟรมเพิ่มเติมเมื่อข้อมูลถูกส่งจากไคลเอนต์ไปยังเซิร์ฟเวอร์รวมถึงการบีบอัดเพิ่มเติมซึ่งต้องใช้ความพยายามในการสอบสวนข้อมูล โปรโตคอลที่ทันสมัยทั้งหมดรองรับทั้ง: HTTP และ HTTPS (เข้ารหัส)

PS

โปรดจำไว้ว่าโดยทั่วไปแล้ว WebSockets จะมีวิธีการทางตรรกะที่แตกต่างกันมากเช่นในเกมแบบเรียลไทม์ซึ่งมีอยู่ตลอดเวลาและไม่ชอบ http


15
มันไม่เกี่ยวกับความเข้ากันได้ของมัน สิ่งสำคัญที่สุดคือการคิดใหม่อย่างเต็มที่ถึงวิธีการสื่อสารที่เกิดขึ้น เนื่องจาก RESTful API ทำงานกับคำขอ> รูปแบบการตอบสนองการสื่อสารแบบสองทิศทางที่นี่จะไม่มีประโยชน์ ดังนั้นการลองใช้ WebSockets เพื่อค้นหา RESTful API - เป็นความพยายามที่แปลกและไม่เห็นประโยชน์ใด ๆ เลย หากคุณต้องการข้อมูลจาก RESTful API แต่ตามเวลาจริงคุณสร้าง WebSockets api เพื่อพุชข้อมูลที่จะทำงานกับการสื่อสารสองทิศทางเช่น WebSockets คุณกำลังพยายามที่จะเปรียบเทียบสิ่งต่าง ๆ ในมุมที่พวกเขาจะไม่เปรียบเทียบ :)
moka

2
สวัสดี @pithhelmet มันทั้งหมดขึ้นอยู่กับซอฟต์แวร์ฝั่งเซิร์ฟเวอร์ (ภาษา / เทคโนโลยี) มันเอง WebSocket เป็นเลเยอร์บน TCP และมีหลายวิธีในการปรับใช้ TCP stream เว็บเซิร์ฟเวอร์ที่ทันสมัยใช้สถาปัตยกรรมตามเหตุการณ์และมีประสิทธิภาพมากกับเธรดพูล คุณใช้เทคโนโลยีใดอยู่ Node.js ใช้เหตุการณ์ที่อยู่เบื้องหลังของ IO และเหตุการณ์ที่มีเธรดเดี่ยวในบริบทการดำเนินการดังนั้นจึงมีประสิทธิภาพที่น่าอัศจรรย์ การใช้เธรดสำหรับแต่ละการเชื่อมต่อ - ไม่มีประสิทธิภาพมากในแง่ของ RAM (1mb + ต่อเธรด) เช่นเดียวกับ CPU เนื่องจากเธรดเหล่านั้นจะไม่ทำงานหรือแย่ลง - การวนรอบไม่สิ้นสุดของการตรวจสอบข้อมูล
moka

4
การทำโพลแบบยาวไม่ใช่วิธีการแก้ไขที่สกปรกและแตกต่างจาก webSocket ทั้งสองมีไว้เพื่อใช้ในสถานการณ์ที่แตกต่างกัน
bagz_man

5
@bagz_man Long Polling เป็นการใช้เทคโนโลยี "แฮ็ค" เพื่อให้ได้ผลลัพธ์ที่เทคโนโลยีไม่ได้รับอนุญาตตามคำนิยามและไม่มีทางเลือกมาตรฐาน เหตุผลที่ Long Polling มีอยู่นั่นคือข้อเท็จจริงที่ว่า WS ไม่ได้เป็นประจำเดือน
moka

4
@moka: ระดับฟรีของ Cloudflare จะรองรับการโจมตี 400 + Gbps ที่ยั่งยืน กระเป๋าเงินของคุณสามารถดูดซับบิล AWS ได้หรือไม่? นอกจากนี้ AWS และ Cloudflare ยังมีมุมมองที่แตกต่างกันเมื่อต้องจัดการกับข้อร้องเรียนที่มากับคุณ มันเป็นสิ่งที่ต้องระลึกไว้เสมอตราบใดที่เรากำลังคุยเรื่องการแลกเปลี่ยนกัน :)
danneu

11

หนึ่งในเทคโนโลยีที่แข่งขันกันที่คุณละเว้นคือเหตุการณ์ที่เซิร์ฟเวอร์ส่ง / แหล่งเหตุการณ์ Long-Polling, Websockets, เหตุการณ์ที่เซิร์ฟเวอร์ส่ง (SSE) และ Comet คืออะไร มีการอภิปรายที่ดีของสิ่งเหล่านี้ทั้งหมด โปรดทราบว่าสิ่งเหล่านี้บางอย่างง่ายกว่าที่อื่น ๆ เพื่อรวมเข้ากับฝั่งเซิร์ฟเวอร์


จากสิ่งเหล่านี้คุณอยากแนะนำให้ลองทำอย่างไร
somdow

ฉันประสบความสำเร็จกับการทำโพลแบบยาวเคล็ดลับเดียว (สำหรับมันและเทคโนโลยีอื่น ๆ ) ไม่ได้ผูกเธรดเซิร์ฟเวอร์ไว้ หากคุณไม่ได้ใช้รหัสเซิร์ฟเวอร์แบบอะซิงโครนัสมันจะไม่ขยายขนาด
bmm6o

1
@somdow Maksims-Mihejevs ตอบคำถามของคุณได้ดีในสองย่อหน้าแรกของคำตอบของเขา ใช้ websockets
Jeff Sheffield

7

สำหรับแอปพลิเคชั่นแชทหรือแอปพลิเคชันอื่น ๆ ที่อยู่ในการสนทนาคงที่กับเซิร์ฟเวอร์WebSocketsเป็นตัวเลือกที่ดีที่สุด อย่างไรก็ตามคุณสามารถใช้WebSocketsกับเซิร์ฟเวอร์ที่รองรับเท่านั้นดังนั้นอาจจำกัดความสามารถในการใช้งานหากคุณไม่สามารถติดตั้งไลบรารีที่ต้องการได้ ในกรณีนี้คุณจะต้องใช้Long Pollingเพื่อรับฟังก์ชั่นที่คล้ายกัน


5
รองรับ WebSockets ทุกเซิร์ฟเวอร์ ... คุณเพียงแค่ติดตั้ง node.js หรือสิ่งที่คล้ายกัน
noob

9
ปรับแต่งเล็กน้อยเพื่ออธิบายว่าใช่เซิร์ฟเวอร์ใด ๆ จะสนับสนุน WebSockets อย่างไรก็ตามหากคุณใช้บริการโฮสติ้งคุณอาจไม่สามารถใช้งานได้
ตัวผู้โอลเซ่น

ฉันรู้ว่ากระทู้นี้ค่อนข้างเก่า แต่ ... WebSockets อาจไม่ใช่คำตอบที่ดีที่สุดสำหรับการสื่อสารแบบสองทิศทางทั้งหมด ฉันเพิ่งสังเกตเห็นว่าเอกสารประกอบสำหรับการสนับสนุนเว็บซ็อกเก็ตของ Spring 4 แสดงให้เห็นว่า WebSockets เหมาะสำหรับการย้ายข้อมูลจำนวนมากหรือเวลาแฝงที่ต่ำ หากสิ่งเหล่านั้นไม่เกี่ยวข้องหรือไม่มีความสำคัญฉันเชื่อว่าพวกเขาแนะนำให้ใช้การสำรวจแบบยาว ฉันไม่ทราบเหตุผลเต็มรูปแบบสำหรับมุมมองนี้ฉันเพิ่งคิดว่าคนในฤดูใบไม้ผลิรู้ว่าสิ่งที่พวกเขากำลังพูดถึงโดยทั่วไป
Stoney

1
@ Stoney นอกเหนือจากข้อเท็จจริงที่ว่าคุณจะต้องติดตั้ง websocket บนเซิร์ฟเวอร์ (ตัวจัดการ ฯลฯ ) ไม่มีเหตุผลที่จะใช้ Long polling ผ่าน websocket Websocket เร็วกว่ามาก (เวลาแฝงต่ำ) และอนุญาตให้เซิร์ฟเวอร์ "พูดคุย" กับลูกค้าโดยที่ลูกค้าไม่ขอ ทุกวันนี้ฉันใช้ signalr (หนึ่งในการใช้งานที่ดีที่สุดของ websocket ที่เคยทำในความคิดของฉัน - มันทำงานบนไคลเอนต์และเซิร์ฟเวอร์และช่วยให้ลูกค้าที่จะเรียกวิธีการบนเซิร์ฟเวอร์และเซิร์ฟเวอร์บนไคลเอนต์ราวกับว่าไม่มีความแตกต่าง) เว็บไซต์ที่ฉันสร้าง - การโหลดเนื้อหาแบบไดนามิกหน้าเว็บที่ไม่มีก้น ฯลฯ
DividedByZero

0

XHR polling vs SSE กับ WebSockets

  • การตอบ XHRคำขอจะเกิดขึ้นเมื่อมีเหตุการณ์เกิดขึ้น (อาจเกิดขึ้นทันทีหรือหลังจากเกิดความล่าช้า) คำขอที่ตามมาจะต้องทำเพื่อรับเหตุการณ์เพิ่มเติม

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

  • เหตุการณ์ที่เซิร์ฟเวอร์ส่งไคลเอนต์ส่งคำขอไปยังเซิร์ฟเวอร์ เซิร์ฟเวอร์ส่งข้อมูลใหม่ไปยังหน้าเว็บได้ตลอดเวลา

    ตามเนื้อผ้าหน้าเว็บต้องส่งคำขอไปยังเซิร์ฟเวอร์เพื่อรับข้อมูลใหม่ นั่นคือหน้าร้องขอข้อมูลจากเซิร์ฟเวอร์ ด้วยเหตุการณ์ที่เซิร์ฟเวอร์ส่งเป็นไปได้ที่เซิร์ฟเวอร์จะส่งข้อมูลใหม่ไปยังหน้าเว็บได้ตลอดเวลาโดยการส่งข้อความไปยังหน้าเว็บ ข้อความขาเข้าเหล่านี้สามารถใช้เป็นข้อมูลกิจกรรม + ในหน้าเว็บ Mozilla

  • WebSocketsหลังจากจับมือเริ่มต้น (ผ่านโปรโตคอล HTTP) การสื่อสารทำได้แบบสองทางโดยใช้โปรโตคอล WebSocket

    การจับมือกันเริ่มต้นด้วยการร้องขอ / ตอบกลับของ HTTP ทำให้เซิร์ฟเวอร์สามารถจัดการการเชื่อมต่อ HTTP รวมถึงการเชื่อมต่อ WebSocket บนพอร์ตเดียวกัน เมื่อสร้างการเชื่อมต่อแล้วการสื่อสารจะเปลี่ยนเป็นโปรโตคอลไบนารีแบบสองทิศทางซึ่งไม่เป็นไปตามโปรโตคอล HTTP วิกิพีเดีย

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