หลังจากอ่านข้อมูลจำเพาะ HTTP / 2เสร็จแล้วฉันคิดว่า HTTP / 2 นั้นล้าสมัย websockets สำหรับกรณีการใช้งานส่วนใหญ่ แต่อาจไม่ทั้งหมด
PUSH_PROMISE
(เรียกขานกันว่าการพุชเซิร์ฟเวอร์) ไม่ใช่ปัญหาที่นี่ นั่นเป็นเพียงการเพิ่มประสิทธิภาพ
กรณีการใช้งานหลักสำหรับ Websockets ในเบราว์เซอร์คือการเปิดใช้งานการสตรีมข้อมูลแบบสองทิศทาง ดังนั้นฉันคิดว่าคำถามของ OP จะกลายเป็นว่า HTTP / 2 ทำงานได้ดีกว่าในการเปิดใช้งานการสตรีมแบบสองทิศทางในเบราว์เซอร์และฉันคิดว่าใช่
อย่างแรกเลยคือ bi-di เพียงอ่านบทนำสู่ส่วนของสตรีม :
"สตรีม" เป็นลำดับที่เป็นอิสระและเป็นแบบสองทิศทางของการแลกเปลี่ยนเฟรมระหว่างไคลเอนต์และเซิร์ฟเวอร์ภายในการเชื่อมต่อ HTTP / 2 ลำธารมีลักษณะสำคัญหลายประการ:
การเชื่อมต่อ HTTP / 2 เดียวสามารถมีสตรีมที่เปิดหลายแห่งพร้อมกันโดยมีจุดปลาย interleaving เฟรมจากหลายสตรีม
สตรีมสามารถสร้างและใช้เพียงฝ่ายเดียวหรือใช้ร่วมกันโดยไคลเอนต์หรือเซิร์ฟเวอร์
สตรีมสามารถปิดได้โดยอุปกรณ์ปลายทาง
บทความเช่นนี้ (เชื่อมโยงกับคำตอบอื่น) ผิดเกี่ยวกับแง่มุมของ HTTP / 2 นี้ พวกเขาบอกว่ามันไม่ใช่ bidi ดูมีสิ่งหนึ่งที่ไม่สามารถเกิดขึ้นได้กับ HTTP / 2: หลังจากเปิดการเชื่อมต่อเซิร์ฟเวอร์จะไม่สามารถเริ่มสตรีมปกติเพียงสตรีมแบบพุชเท่านั้น แต่เมื่อลูกค้าเปิดสตรีมด้วยการส่งคำขอทั้งสองฝ่ายสามารถส่งเฟรมข้อมูลไปยังซ็อกเก็ตแบบถาวรได้ตลอดเวลา - เต็มเต็ม
นั่นไม่ได้แตกต่างจาก websockets มากนัก: ลูกค้าต้องเริ่มต้นคำขออัพเกรด websocket ก่อนที่เซิร์ฟเวอร์จะสามารถส่งข้อมูลได้เช่นกัน
ความแตกต่างที่ใหญ่ที่สุดคือ HTTP / 2 จะกำหนดความหมายเชิงมัลติเพล็กซ์ของตัวเองซึ่งแตกต่างจาก websockets คือวิธีที่สตรีมได้รับตัวระบุและวิธีที่เฟรมนำเสนอไอดีของสตรีมที่อยู่บนนั้น HTTP / 2 ยังกำหนด semantics ควบคุมการไหลสำหรับการจัดลำดับความสำคัญลำธาร นี่เป็นสิ่งสำคัญในแอปพลิเคชัน bidi ที่ใช้งานจริง
(บทความที่ผิดยังบอกว่ามาตรฐาน Websocket มีมัลติเพล็กซ์ไม่มันไม่ยากเลยที่จะหามันแค่เปิด Websocket RFC 6455และกด⌘-F แล้วพิมพ์ "มัลติเพล็กซ์" หลังจากอ่านแล้ว
โปรโตคอลนี้มีจุดประสงค์เพื่อให้สามารถขยายได้ เวอร์ชันในอนาคตมีแนวโน้มที่จะแนะนำแนวคิดเพิ่มเติมเช่นมัลติเพล็กซ์
คุณจะพบว่ามีส่วนขยายร่าง 2013 สำหรับการทำมัลติเพล็กซิ่ง Websocket แต่ฉันไม่ทราบว่ามีเบราว์เซอร์ใดบ้างที่สนับสนุน ฉันจะไม่พยายามสร้าง webapp SPA ของฉันที่ด้านหลังของส่วนขยายนั้นโดยเฉพาะอย่างยิ่งเมื่อมี HTTP / 2 มาการสนับสนุนอาจไม่มาถึง)
การทำ Multiplexing เป็นสิ่งที่คุณต้องทำด้วยตัวเองทุกครั้งที่คุณเปิด websocket สำหรับ bidi พูดเพื่อเพิ่มประสิทธิภาพให้แอพพลิเคชั่นหน้าเดียวแบบโต้ตอบ ฉันดีใจที่มันอยู่ในข้อมูลจำเพาะ HTTP / 2 ได้รับการดูแลทันทีและทั้งหมด
ถ้าคุณต้องการทราบว่า HTTP / 2 สามารถทำอะไรได้แค่ดู gRPC gRPC ถูกนำไปใช้กับ HTTP / 2 ดูตัวเลือกการสตรีมมิ่งครึ่งและเต็มเพล็กซ์ที่ gRPC นำเสนอโดยเฉพาะ (โปรดทราบว่าขณะนี้ gRPC ไม่สามารถใช้งานได้ในเบราว์เซอร์ แต่นั่นเป็นเพราะเบราว์เซอร์ (1) ไม่เปิดเผยเฟรม HTTP / 2 ไปยังไคลเอ็นต์ javascript และ (2) ไม่สนับสนุนตัวอย่างทั่วไปซึ่งใช้ใน ข้อมูลจำเพาะ gRPC)
เว็บซ็อคเก็ตอาจจะมีที่ไหน เบราว์เซอร์ตัวใหญ่คือเซิร์ฟเวอร์ -> เบราว์เซอร์ผลักข้อมูลไบนารี HTTP / 2 อนุญาตให้เซิร์ฟเวอร์ -> เบราว์เซอร์ผลักข้อมูลไบนารี แต่จะไม่เปิดเผยในเบราว์เซอร์ JS สำหรับแอปพลิเคชันเช่นการผลักเฟรมเสียงและวิดีโอนี่คือเหตุผลที่ใช้เว็บซ็อกเก็ต
แก้ไข: Jan 17 2020
เมื่อเวลาผ่านไปคำตอบนี้จะค่อยๆสูงขึ้นไปด้านบน (ซึ่งก็ดีเพราะคำตอบนี้ถูกต้องมากกว่าหรือน้อยกว่า) อย่างไรก็ตามยังมีความคิดเห็นเป็นครั้งคราวที่บอกว่ามันไม่ถูกต้องด้วยเหตุผลหลายประการซึ่งมักเกี่ยวข้องกับความสับสนPUSH_PROMISE
หรือวิธีการใช้เซิร์ฟเวอร์ที่มุ่งเน้นข้อความ -> ไคลเอนต์พุชในแอปหน้าเดียว และมีกรณีการใช้งานสำหรับ websockets ในเบราว์เซอร์ซึ่งเป็นข้อมูลไบนารีที่เซิร์ฟเวอร์ผลัก สำหรับข้อมูลที่เป็นข้อความรวมถึง JSON อย่าใช้ websockets ใช้ SSE
ในการสรุป: โปรโตคอล HTTP / 2 นั้นเต็มไปด้วยสองส่วน อย่างไรก็ตามเว็บเบราว์เซอร์ที่ทันสมัยอย่าให้กรอบเชิง HTTP / 2 โปรโตคอล JavaScript ไม่อย่างนั้นถ้าคุณทำการร้องขอหลายครั้งไปยังจุดกำเนิดเดียวกันผ่านการเชื่อมต่อ HTTP / 2 ภายใต้ประทุนการรับส่งข้อมูลทั้งหมดนั้นได้รับการเชื่อมต่อแบบหลายจุดในการเชื่อมต่อเดียว (และนั่นคือสิ่งที่เราใส่ใจ!)
ดังนั้นหากคุณต้องการสร้างแอปแชทเรียลไทม์สมมติว่าคุณต้องการถ่ายทอดข้อความแชทใหม่ให้กับลูกค้าทุกคนในห้องสนทนาที่มีการเชื่อมต่อแบบเปิดคุณสามารถทำได้
คุณจะใช้เหตุการณ์ที่ส่งโดยเซิร์ฟเวอร์เพื่อส่งข้อความลงและFetch api เพื่อส่งคำขอ เหตุการณ์ที่เซิร์ฟเวอร์ส่ง (SSE) เป็นAPI ที่รู้จักกันน้อย แต่ได้รับการสนับสนุนเป็นอย่างดีซึ่งทำให้มีการสตรีมเซิร์ฟเวอร์กับไคลเอ็นต์ แม้ว่ามันจะดูไม่เหมือนกับ JavaScript ของไคลเอ็นต์ แต่ภายใต้ฮูดเบราว์เซอร์ของคุณ (หากรองรับ HTTP / 2) จะใช้การเชื่อมต่อ TCP เดียวเพื่อนำข้อความทั้งหมดเหล่านี้กลับมาใช้ซ้ำอีกครั้ง ไม่มีการสูญเสียประสิทธิภาพและในความเป็นจริงมันได้รับมากกว่า websockets ต้องการสตรีมหลายรายการหรือไม่ เปิด EventSources หลายรายการ! พวกเขาจะถูก multiplexed โดยอัตโนมัติสำหรับคุณ
นอกเหนือจากการใช้ทรัพยากรอย่างมีประสิทธิภาพมากขึ้นและมีเวลาแฝงเริ่มต้นน้อยกว่าการจับมือกันของ websocket เหตุการณ์ที่เซิร์ฟเวอร์ส่งมีคุณสมบัติที่ดีที่พวกเขาย้อนกลับโดยอัตโนมัติและทำงานผ่าน HTTP / 1.1 แต่เมื่อคุณมีการเชื่อมต่อ HTTP / 2 มันทำงานได้ดีอย่างไม่น่าเชื่อ
นี่คือบทความที่ดีพร้อมตัวอย่างจริงของการทำสปาที่มีการปรับปรุงใหม่