เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์

เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
ซอฟต์แวร์ในรูปแบบบริการ โครงสร้างพื้นฐานในรูปแบบบริการ แพลตฟอร์มในรูปแบบบริการ แพลตฟอร์มการสื่อสารในรูปแบบบริการ การประชุมทางวิดีโอในรูปแบบบริการ แล้วบริการเกมบนคลาวด์ล่ะ มีความพยายามหลายครั้งในการสร้างเกมบนคลาวด์ (Cloud Gaming) เช่น Stadia ซึ่งเพิ่งเปิดตัวโดย Google สตาเดีย ไม่ใช่เรื่องใหม่สำหรับ WebRTCแต่คนอื่นสามารถใช้ WebRTC ในลักษณะเดียวกันได้หรือไม่

Thanh Nguyen ตัดสินใจทดสอบโอกาสนี้กับโปรเจ็กต์โอเพ่นซอร์ส CloudRetro ของเขา CloudRetro ขึ้นอยู่กับ Pion เป็นที่นิยม ไลบรารี WebRTC ที่ใช้ Go (ขอบคุณ ชยอนู จากทีมพัฒนา Pion เพื่อขอความช่วยเหลือในการจัดทำบทความนี้) ในบทความนี้ Thanh ให้ภาพรวมของสถาปัตยกรรมของโครงการของเขา และยังพูดถึงสิ่งที่มีประโยชน์ที่เขาได้เรียนรู้ และความท้าทายที่เขาพบระหว่างการทำงาน

การเข้า

เมื่อปีที่แล้วเมื่อ Google ประกาศ Stadia มันทำให้ฉันทึ่ง แนวคิดนี้มีเอกลักษณ์และเป็นนวัตกรรมใหม่มากจนฉันสงสัยอยู่ตลอดเวลาว่าสิ่งนี้เป็นไปได้อย่างไรด้วยเทคโนโลยีที่มีอยู่ ความปรารถนาที่จะเข้าใจหัวข้อนี้ดีขึ้นทำให้ฉันต้องสร้างเกมโอเพ่นซอร์สบนคลาวด์เวอร์ชันของตัวเอง ผลลัพธ์ที่ได้นั้นยอดเยี่ยมมาก ด้านล่างนี้ฉันต้องการแบ่งปันกระบวนการทำงานในปีของฉัน โครงการ.

TLDR: เวอร์ชันสไลด์สั้นพร้อมไฮไลต์

ทำไมการเล่นเกมบนคลาวด์จึงเป็นอนาคต

ฉันเชื่อว่าในไม่ช้า Cloud Gaming จะกลายเป็นเกมยุคถัดไปไม่เพียงแต่เกมเท่านั้น แต่ยังรวมไปถึงสาขาอื่น ๆ ของวิทยาการคอมพิวเตอร์ด้วย การเล่นเกมบนคลาวด์ถือเป็นจุดสุดยอดของโมเดลไคลเอนต์/เซิร์ฟเวอร์ โมเดลนี้เพิ่มการจัดการแบ็กเอนด์สูงสุดและลดการทำงานของฟรอนต์เอนด์ด้วยการโฮสต์ตรรกะเกมบนเซิร์ฟเวอร์ระยะไกลและสตรีมรูปภาพ/เสียงไปยังไคลเอนต์ เซิร์ฟเวอร์ทำการประมวลผลอย่างหนัก ดังนั้นไคลเอนต์จึงไม่ต้องอยู่ภายใต้ข้อจำกัดด้านฮาร์ดแวร์อีกต่อไป

Google Stadia ช่วยให้คุณเล่นได้เป็นหลัก เกมระดับเอเอ (เช่น เกมบล็อกบัสเตอร์ระดับไฮเอนด์) บนอินเทอร์เฟซเช่น YouTube วิธีการเดียวกันนี้สามารถนำไปใช้กับแอปพลิเคชันออฟไลน์ขนาดใหญ่อื่นๆ ได้ เช่น ระบบปฏิบัติการหรือการออกแบบกราฟิก 2D/3D เป็นต้น เพื่อให้เราสามารถรันได้อย่างต่อเนื่องบนอุปกรณ์สเปคต่ำบนหลายแพลตฟอร์ม

เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
อนาคตของเทคโนโลยีนี้: ลองนึกดูว่า Microsoft Windows 10 ทำงานบนเบราว์เซอร์ Chrome หรือไม่

การเล่นเกมบนคลาวด์ถือเป็นความท้าทายทางเทคนิค

การเล่นเกมเป็นหนึ่งในพื้นที่ที่หายากซึ่งจำเป็นต้องตอบสนองผู้ใช้อย่างต่อเนื่องและรวดเร็ว หากบางครั้งเราพบความล่าช้า 2 วินาทีเมื่อคลิกบนหน้าเว็บ ก็ถือว่ายอมรับได้ การสตรีมวิดีโอสดมักจะล่าช้าไม่กี่วินาที แต่ก็ยังมีการใช้งานที่สมเหตุสมผล อย่างไรก็ตาม หากเกมล่าช้าถึง 500ms บ่อยครั้ง แสดงว่าไม่สามารถเล่นได้ เป้าหมายของเราคือการบรรลุเวลาแฝงที่ต่ำมาก เพื่อให้ช่องว่างระหว่างอินพุตและสื่อมีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้ ดังนั้นวิธีการดั้งเดิมในการสตรีมวิดีโอจึงไม่สามารถใช้ได้ที่นี่

เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
เทมเพลตเกมคลาวด์ทั่วไป

โปรเจ็กต์โอเพ่นซอร์ส CloudRetro

ฉันตัดสินใจสร้างตัวอย่างทดสอบของเกมบนคลาวด์เพื่อดูว่าทั้งหมดนี้เป็นไปได้หรือไม่ภายใต้ข้อจำกัดด้านเครือข่ายที่แน่นหนาเช่นนี้ ฉันเลือก Golang เพื่อพิสูจน์แนวคิดเพราะเป็นภาษาที่ฉันคุ้นเคยมากที่สุดและเหมาะสมอย่างยิ่งสำหรับการใช้งานนี้ด้วยเหตุผลอื่นๆ มากมาย ดังที่ฉันค้นพบในภายหลัง Go นั้นเรียบง่ายและพัฒนาได้เร็วมาก Channels in Go นั้นยอดเยี่ยมสำหรับการจัดการมัลติเธรด

โครงการ CloudRetro.io เป็นบริการเกมบนคลาวด์แบบโอเพ่นซอร์สสำหรับการเล่นเกมย้อนยุค เป้าหมายของโปรเจ็กต์คือการนำประสบการณ์การเล่นเกมที่สะดวกสบายที่สุดมาสู่เกมย้อนยุคแบบดั้งเดิมและเพิ่มผู้เล่นหลายคน
คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับโครงการได้ที่นี่: https://github.com/giongto35/cloud-game.

ฟังก์ชั่น CloudRetro

CloudRetro ใช้เกมย้อนยุคเพื่อแสดงให้เห็นถึงพลังของเกมบนคลาวด์ ซึ่งทำให้คุณได้รับประสบการณ์การเล่นเกมที่ไม่เหมือนใครมากมาย

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

  • เซสชันเกมสามารถแชร์ผ่านอุปกรณ์หลายเครื่องและจัดเก็บไว้ในระบบคลาวด์สำหรับครั้งต่อไปที่คุณเข้าสู่ระบบ
  • เกมสามารถสตรีมหรือเล่นโดยผู้ใช้หลายคนพร้อมกัน:
    • การเล่นแบบ Crowdplay เช่น TwitchPlayPokemon มีเพียงข้ามแพลตฟอร์มและเรียลไทม์มากขึ้นเท่านั้น
    • เกมออฟไลน์ออนไลน์ ผู้ใช้หลายคนสามารถเล่นได้โดยไม่ต้องตั้งค่าเครือข่าย Samurai Shurai สามารถเล่นได้ 2 คนผ่านเครือข่าย CloudRetro แล้ว

    เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
    เวอร์ชันสาธิตของเกมผู้เล่นหลายคนออนไลน์บนอุปกรณ์ต่างๆ

    โครงสร้างพื้นฐาน

    ข้อกำหนดและเทคโนโลยีกองซ้อน

    ด้านล่างนี้คือรายการข้อกำหนดที่ฉันกำหนดไว้ก่อนเริ่มโครงการ

    1. ผู้เล่นหนึ่งคน
    ข้อกำหนดนี้อาจดูไม่สำคัญหรือชัดเจนเกินไปในที่นี้ แต่เป็นหนึ่งในประเด็นสำคัญของฉัน เพราะช่วยให้การเล่นเกมบนคลาวด์อยู่ห่างจากบริการสตรีมมิ่งแบบเดิมๆ มากที่สุดเท่าที่จะเป็นไปได้ หากเรามุ่งเน้นไปที่เกมที่มีผู้เล่นคนเดียว เราก็สามารถกำจัดเซิร์ฟเวอร์ส่วนกลางหรือ CDN ได้ เนื่องจากเราไม่จำเป็นต้องสตรีมไปยังคนจำนวนมาก แทนที่จะอัปโหลดสตรีมไปยังเซิร์ฟเวอร์ซิงก์หรือส่งแพ็กเก็ตไปยังเซิร์ฟเวอร์ WebSocket แบบรวมศูนย์ สตรีมบริการจะถูกส่งโดยตรงไปยังผู้ใช้ผ่านการเชื่อมต่อ WebRTC แบบเพียร์ทูเพียร์

    2. กระแสสื่อแฝงต่ำ
    เมื่ออ่านเกี่ยวกับ Stadia ฉันมักจะเห็น WebRTC กล่าวถึงในบางบทความ ฉันตระหนักว่า WebRTC เป็นเทคโนโลยีที่โดดเด่นและเหมาะสำหรับใช้ในเกมบนคลาวด์ WebRTC เป็นโครงการที่ให้บริการเว็บเบราว์เซอร์และแอปพลิเคชันมือถือด้วยการสื่อสารแบบเรียลไทม์ผ่าน API ที่เรียบง่าย มีการเชื่อมต่อแบบเพียร์ทูเพียร์ ได้รับการปรับให้เหมาะกับสื่อ และมีตัวแปลงสัญญาณมาตรฐานในตัว เช่น VP8 และ H264

    ฉันให้ความสำคัญกับการรับรองประสบการณ์ผู้ใช้ที่ดีที่สุดเท่าที่จะเป็นไปได้มากกว่าการรักษากราฟิกคุณภาพสูง การสูญเสียบางอย่างเป็นที่ยอมรับในอัลกอริทึม Google Stadia มีขั้นตอนเพิ่มเติมในการลดขนาดรูปภาพบนเซิร์ฟเวอร์ และเฟรมต่างๆ จะได้รับการอัปเกรดให้มีคุณภาพสูงขึ้นก่อนที่จะส่งไปยังอุปกรณ์อื่นๆ

    3. โครงสร้างพื้นฐานแบบกระจายพร้อมการกำหนดเส้นทางทางภูมิศาสตร์
    ไม่ว่าอัลกอริธึมการบีบอัดและโค้ดจะปรับให้เหมาะสมเพียงใด เครือข่ายยังคงเป็นปัจจัยในการตัดสินใจที่ทำให้เกิดความล่าช้ามากที่สุด สถาปัตยกรรมจะต้องมีกลไกในการจับคู่เซิร์ฟเวอร์ที่ใกล้กับผู้ใช้มากที่สุดเพื่อลดเวลาไปกลับ (RTT) สถาปัตยกรรมจะต้องมีผู้ประสานงาน 1 คนและเซิร์ฟเวอร์สตรีมมิ่งหลายแห่งที่กระจายอยู่ทั่วโลก: สหรัฐอเมริกาตะวันตก สหรัฐอเมริกาตะวันออก ยุโรป สิงคโปร์ จีน เซิร์ฟเวอร์สตรีมมิ่งทั้งหมดจะต้องแยกออกจากกันโดยสิ้นเชิง ระบบสามารถปรับการกระจายเมื่อเซิร์ฟเวอร์เข้าร่วมหรือออกจากเครือข่าย ดังนั้นเมื่อมีการรับส่งข้อมูลจำนวนมาก การเพิ่มเซิร์ฟเวอร์เพิ่มเติมจึงทำให้สามารถปรับขนาดแนวนอนได้

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

    5. แยกอินเทอร์เฟซเกมและบริการอย่างชัดเจน
    ฉันมองว่าบริการเกมบนคลาวด์เป็นแพลตฟอร์ม ทุกคนควรจะสามารถเชื่อมต่อทุกสิ่งเข้ากับแพลตฟอร์มได้ ตอนนี้ผมได้บูรณาการแล้ว LibRetro ด้วยบริการเกมบนคลาวด์ เนื่องจาก LibRetro มีอินเทอร์เฟซจำลองเกมที่สวยงามสำหรับเกมย้อนยุค เช่น SNES, GBA, PS

    6. ห้องสำหรับผู้เล่นหลายคน การเล่นแบบฝูงชน และการเชื่อมโยงภายนอก (ลิงก์เชิงลึก) กับเกม
    CloudRetro รองรับการเล่นเกมใหม่ๆ มากมาย เช่น CrowdPlay และ Online MultiPlayer สำหรับเกมย้อนยุค หากผู้ใช้หลายคนเปิดลิงก์ในรายละเอียดเดียวกันบนคอมพิวเตอร์เครื่องอื่น พวกเขาจะเห็นเกมที่กำลังรันอยู่และจะสามารถเข้าร่วมได้

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

    7. การปรับขนาดแนวนอน
    เช่นเดียวกับ SAAS อื่นๆ ในปัจจุบัน เกมบนคลาวด์ต้องได้รับการออกแบบให้ปรับขนาดได้ในแนวนอน การออกแบบผู้ประสานงาน-ผู้ปฏิบัติงานช่วยให้คุณสามารถเพิ่มผู้ปฏิบัติงานเพื่อรองรับการรับส่งข้อมูลได้มากขึ้น

    8. ไม่มีการเชื่อมต่อกับคลาวด์เดียว
    โครงสร้างพื้นฐานของ CloudRetro โฮสต์อยู่บนผู้ให้บริการคลาวด์หลายราย (Digital Ocean, Alibaba, ผู้ให้บริการแบบกำหนดเอง) สำหรับภูมิภาคต่างๆ ฉันเปิดใช้งานการทำงานในคอนเทนเนอร์ Docker สำหรับโครงสร้างพื้นฐานและกำหนดการตั้งค่าเครือข่ายโดยใช้สคริปต์ทุบตีเพื่อหลีกเลี่ยงการถูกล็อคเข้ากับผู้ให้บริการคลาวด์รายเดียว เมื่อรวมสิ่งนี้เข้ากับ NAT Traversal ใน WebRTC เราจึงมีความยืดหยุ่นในการปรับใช้ CloudRetro บนแพลตฟอร์มคลาวด์ใดๆ และแม้แต่บนเครื่องของผู้ใช้ทุกคน

    การออกแบบสถาปัตยกรรม

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

    ผู้ประสานงาน: มีหน้าที่จับคู่ผู้ใช้ใหม่กับผู้ปฏิบัติงานที่เหมาะสมที่สุดสำหรับการสตรีม ผู้ประสานงานโต้ตอบกับพนักงานผ่าน WebSocket

    ที่เก็บข้อมูลสถานะของเกม: ที่เก็บข้อมูลระยะไกลส่วนกลางสำหรับสถานะเกมทั้งหมด ที่เก็บข้อมูลนี้มีฟังก์ชันที่สำคัญ เช่น บันทึก/โหลดระยะไกล

    เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
    สถาปัตยกรรมระดับสูงสุดของ CloudRetro

    สคริปต์ที่กำหนดเอง

    เมื่อผู้ใช้ใหม่เปิด CloudRetro ในขั้นตอนที่ 1 และ 2 ดังแสดงในรูปด้านล่าง ผู้ประสานงานพร้อมรายชื่อผู้ปฏิบัติงานที่พร้อมใช้งานจะถูกขอให้ไปที่หน้าแรก หลังจากนี้ ในขั้นตอนที่ 3 ไคลเอนต์จะคำนวณความล่าช้าสำหรับผู้สมัครทั้งหมดโดยใช้คำขอ Ping ของ HTTP รายการความล่าช้านี้จะถูกส่งกลับไปยังผู้ประสานงานเพื่อที่เขาจะได้กำหนดผู้ปฏิบัติงานที่เหมาะสมที่สุดที่จะให้บริการผู้ใช้ ขั้นตอนที่ 4 ด้านล่างสร้างเกม การเชื่อมต่อสตรีมมิ่ง WebRTC ถูกสร้างขึ้นระหว่างผู้ใช้และพนักงานที่ได้รับมอบหมาย
    เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
    สคริปต์ผู้ใช้หลังจากเข้าถึงได้

    มีอะไรอยู่ข้างในคนงาน

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

    เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
    ปฏิสัมพันธ์ของส่วนประกอบของผู้ปฏิบัติงาน

    องค์ประกอบหลัก:

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

    การดำเนินงาน

    CloudRetro อาศัย WebRTC เป็นเทคโนโลยีหลัก ดังนั้นก่อนที่จะเจาะลึกรายละเอียดของการใช้งาน Golang ฉันจึงตัดสินใจพูดคุยเกี่ยวกับ WebRTC ก่อน นี่เป็นเทคโนโลยีที่น่าทึ่งที่ช่วยฉันอย่างมากในการบรรลุเวลาแฝงที่ต่ำกว่าวินาทีสำหรับการสตรีมข้อมูล

    WebRTC

    WebRTC ได้รับการออกแบบมาเพื่อมอบการเชื่อมต่อแบบเพียร์ทูเพียร์คุณภาพสูงบนแอปมือถือและเบราว์เซอร์แบบเนทีฟโดยใช้ API แบบธรรมดา

    การข้ามผ่านของ NAT

    WebRTC มีชื่อเสียงในด้านฟังก์ชัน NAT Traversal WebRTC ได้รับการออกแบบมาเพื่อการสื่อสารแบบเพียร์ทูเพียร์ เป้าหมายคือการค้นหาเส้นทางตรงที่เหมาะสมที่สุด โดยหลีกเลี่ยงเกตเวย์ NAT และไฟร์วอลล์สำหรับการสื่อสารแบบเพียร์ทูเพียร์ผ่านกระบวนการที่เรียกว่า ICE. ในส่วนหนึ่งของกระบวนการนี้ WebRTC API จะค้นหาที่อยู่ IP สาธารณะของคุณโดยใช้เซิร์ฟเวอร์ STUN และส่งต่อไปยังเซิร์ฟเวอร์รีเลย์ (กลับ) เมื่อไม่สามารถสร้างการเชื่อมต่อโดยตรงได้

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

    ก่อนหน้านี้ ฉันต้องการเปลี่ยนโปรเจ็กต์นี้ให้เป็นแพลตฟอร์มการจัดจำหน่ายเกมสำหรับ Cloud Gaming แนวคิดคือการอนุญาตให้ผู้สร้างเกมสามารถจัดหาเกมและทรัพยากรการสตรีมได้ และผู้ใช้ก็จะโต้ตอบกับผู้ให้บริการโดยตรง ในลักษณะการกระจายอำนาจนี้ CloudRetro เป็นเพียงเฟรมเวิร์กสำหรับเชื่อมต่อทรัพยากรการสตรีมของบุคคลที่สามกับผู้ใช้ ทำให้สามารถปรับขนาดได้มากขึ้นเมื่อไม่ได้โฮสต์อีกต่อไป บทบาทของ WebRTC NAT Traversal ที่นี่มีความสำคัญมากในการอำนวยความสะดวกในการเริ่มต้นการเชื่อมต่อแบบ peer-to-peer บนทรัพยากรการสตรีมของบุคคลที่สาม ทำให้ผู้สร้างสามารถเชื่อมต่อกับเครือข่ายได้ง่ายขึ้น

    การบีบอัดวิดีโอ

    การบีบอัดวิดีโอเป็นส่วนสำคัญของไปป์ไลน์และมีส่วนช่วยให้การไหลราบรื่นอย่างมาก แม้ว่าจะไม่จำเป็นต้องทราบทุกรายละเอียดของการเข้ารหัสวิดีโอ VP8/H264 แต่การทำความเข้าใจแนวคิดสามารถช่วยให้คุณเข้าใจตัวเลือกความเร็ววิดีโอสตรีมมิง แก้ไขข้อบกพร่องพฤติกรรมที่ไม่คาดคิด และปรับเวลาแฝงได้

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

    แนวคิดเบื้องหลังการบีบอัดวิดีโอคือการกำจัดบิตข้อมูลที่ไม่จำเป็น ในขณะเดียวกันก็รักษาระดับความแม่นยำที่ยอมรับได้สำหรับผู้ใช้ นอกเหนือจากการเข้ารหัสเฟรมภาพนิ่งแต่ละเฟรมแล้ว อัลกอริธึมยังสรุปเฟรมปัจจุบันจากเฟรมก่อนหน้าและถัดไป ดังนั้นจะส่งเฉพาะส่วนต่างเท่านั้น ดังที่เห็นได้จากตัวอย่าง Pacman จะมีการส่งเฉพาะจุดส่วนต่างเท่านั้น

    เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
    เปรียบเทียบเฟรมวิดีโอโดยใช้ Pacman เป็นตัวอย่าง

    การบีบอัดเสียง

    ในทำนองเดียวกัน อัลกอริธึมการบีบอัดเสียงจะละเว้นข้อมูลที่มนุษย์ไม่สามารถรับรู้ได้ ปัจจุบัน Opus เป็นตัวแปลงสัญญาณเสียงที่มีประสิทธิภาพดีที่สุด ได้รับการออกแบบมาเพื่อส่งคลื่นเสียงผ่านโปรโตคอลดาตาแกรมที่ได้รับคำสั่ง เช่น RTP (Real Time Transport Protocol) เวลาแฝงต่ำกว่า mp3 และ aac และคุณภาพสูงกว่า เวลาแฝงมักจะอยู่ที่ประมาณ 5~66,5ms

    Pion, WebRTC ใน Golang

    pion เป็นโครงการโอเพ่นซอร์สที่นำ WebRTC มาสู่ Golang แทนที่จะรวมไลบรารี C++ WebRTC แบบเนทีฟตามปกติ Pion เป็นการนำ Golang ไปใช้ WebRTC โดยมีประสิทธิภาพที่ดีกว่า การผสานรวม Go และการควบคุมเวอร์ชันบนโปรโตคอล WebRTC

    ไลบรารียังเปิดใช้งานการสตรีมด้วยบิวท์อินที่ยอดเยี่ยมมากมายพร้อมเวลาแฝงที่ต่ำกว่าวินาที มีการใช้งาน STUN, DTLS, SCTP และอื่น ๆ ของตัวเอง และการทดลองบางอย่างกับ QUIC และ WebAssembly ไลบรารีโอเพ่นซอร์สนี้เป็นแหล่งการเรียนรู้ที่ดีมากพร้อมเอกสารประกอบที่ยอดเยี่ยม การใช้งานโปรโตคอลเครือข่าย และตัวอย่างที่ยอดเยี่ยม

    ชุมชน Pion ซึ่งนำโดยผู้สร้างที่มีความกระตือรือร้นเป็นอย่างมาก ค่อนข้างมีชีวิตชีวา โดยมีการพูดคุยที่มีคุณภาพมากมายเกี่ยวกับ WebRTC หากคุณสนใจเทคโนโลยีนี้เข้าร่วม http://pion.ly/slack – คุณจะได้เรียนรู้สิ่งใหม่ๆ มากมาย

    การเขียน CloudRetro ใน Golang

    เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
    การใช้งานคนงานใน Go

    ไปที่ช่องในการดำเนินการ

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

    func (e *gameEmulator) gameUpdate() {
    for {
    	select {
    		case <-e.saveOperation:
    			e.saveGameState()
    		case key := <-e.input:
    			e.updateGameState(key)
    		case <-e.done:
    			e.close()
    			return
    	}
        }
    }

    พัดลมเข้า/พัดลมออก

    เทมเพลต Golang นี้เหมาะกับกรณีการใช้งาน CrowdPlay และผู้เล่นหลายคนของฉันอย่างสมบูรณ์แบบ ตามรูปแบบนี้ อินพุตของผู้ใช้ทั้งหมดในห้องเดียวจะถูกสร้างขึ้นในช่องทางเข้ากลาง จากนั้นสื่อเกมจะถูกนำไปใช้กับผู้ใช้ทุกคนในห้องเดียวกัน ด้วยวิธีนี้ เราจึงสามารถแบ่งสถานะเกมระหว่างเซสชันเกมต่างๆ ของผู้ใช้ที่แตกต่างกันได้

    เกมโอเพ่นซอร์สบนคลาวด์บน WebRTC: p2p, ผู้เล่นหลายคน, เวลาแฝงเป็นศูนย์
    การซิงโครไนซ์ระหว่างเซสชันต่างๆ

    ข้อเสียของโกลัง

    โกลังไม่สมบูรณ์แบบ ช่องมันช้า. เมื่อเปรียบเทียบกับการบล็อก Go channel เป็นวิธีที่ง่ายกว่าในการจัดการเหตุการณ์ที่เกิดขึ้นพร้อมกันและแบบเธรด แต่ช่องทางไม่ได้ให้ประสิทธิภาพที่ดีที่สุด มีตรรกะการบล็อกที่ซับซ้อนอยู่ใต้ช่องสัญญาณ ดังนั้นฉันจึงทำการปรับเปลี่ยนการใช้งานบางอย่าง โดยนำการล็อกและค่าอะตอมมิกมาใช้ใหม่เมื่อเปลี่ยนช่องสัญญาณเพื่อเพิ่มประสิทธิภาพ

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

    ฟันเฟือง

    โปรเจ็กต์นี้ใช้ไลบรารีโอเพ่นซอร์ส Golang VP8/H264 ที่มีอยู่สำหรับการบีบอัดสื่อ และใช้ Libretro สำหรับโปรแกรมจำลองเกม ไลบรารีทั้งหมดเหล่านี้เป็นเพียงส่วนรวมของไลบรารี C ที่ใช้งาน Go ฟันเฟือง. ข้อเสียบางประการมีการระบุไว้ใน โพสต์นี้โดย Dave Cheney. ปัญหาที่ฉันพบ:

    • ไม่สามารถตรวจจับความผิดพลาดใน CGO ได้แม้จะมี Golang RecoveryCrash ก็ตาม
    • ความล้มเหลวในการระบุปัญหาคอขวดของประสิทธิภาพเมื่อเราไม่สามารถตรวจพบปัญหาโดยละเอียดใน CGO

    ข้อสรุป

    ฉันบรรลุเป้าหมายในการทำความเข้าใจบริการเกมบนคลาวด์และสร้างแพลตฟอร์มที่ช่วยให้ฉันเล่นเกมย้อนยุคชวนคิดถึงกับเพื่อน ๆ ทางออนไลน์ได้ โครงการนี้คงเป็นไปไม่ได้หากปราศจากห้องสมุด Pion และการสนับสนุนจากชุมชน Pion ฉันรู้สึกขอบคุณอย่างมากสำหรับการพัฒนาอย่างเข้มข้น API แบบง่ายที่ WebRTC และ Pion มอบให้ทำให้มั่นใจได้ถึงการผสานรวมที่ราบรื่น การพิสูจน์แนวคิดครั้งแรกของฉันได้รับการเผยแพร่ในสัปดาห์เดียวกันนั้น แม้ว่าฉันจะไม่มีความรู้เกี่ยวกับการสื่อสารแบบเพียร์ทูเพียร์ (P2P) มาก่อนก็ตาม

    แม้จะมีความง่ายในการบูรณาการ แต่การสตรีม P2P ถือเป็นพื้นที่ที่ซับซ้อนมากในวิทยาการคอมพิวเตอร์ เธอต้องจัดการกับความซับซ้อนของสถาปัตยกรรมเครือข่ายที่มีมายาวนาน เช่น IP และ NAT เพื่อสร้างเซสชันแบบเพียร์ทูเพียร์ ในขณะที่ทำงานในโครงการนี้ ฉันได้รับความรู้อันมีค่ามากมายเกี่ยวกับเครือข่ายและการเพิ่มประสิทธิภาพ ดังนั้นฉันขอแนะนำให้ทุกคนลองสร้างผลิตภัณฑ์ P2P โดยใช้ WebRTC

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

ที่มา: will.com

เพิ่มความคิดเห็น