นี่คือการใช้งาน C ++ (11) การใช้งานโปรโตคอลการไหลแบบเรียลไทม์ (RTMFP) ที่ปลอดภัยตามที่อธิบายไว้ใน RFC 7016
ไลบรารีรวมถึงอะแดปเตอร์แพลตฟอร์มตัวอย่างและยูทิลิตี้อื่น ๆ เช่นการเรียก select() แบบใช้งานง่าย แต่ไม่จำเป็นต้องใช้สิ่งเหล่านี้ การใช้งานโปรโตคอลมีวัตถุประสงค์เพื่อปรับให้เข้ากับสภาพแวดล้อมของโปรแกรมโฮสต์ใด ๆ
ห้องสมุดมีไว้สำหรับลูกค้าเซิร์ฟเวอร์และแอปพลิเคชัน P2P มันรวมถึงผู้ช่วยที่จำเป็นและตะขอการโทรกลับเพื่อรองรับการแนะนำ P2P และการปรับสมดุลโหลด
ไดเรกทอรี test รวมถึงการทดสอบหน่วยและตัวอย่าง ของโน้ตพิเศษคือ tcserver ซึ่งเป็นเซิร์ฟเวอร์สื่อสด RTMFP และ RTMP ที่เรียบง่าย tcrelay รีเลย์ RTMFP ↔︎ RTMP/พร็อกซี; และ redirector , Load Balancer อย่างง่าย
เอกสาร API ที่สมบูรณ์ที่สุดในปัจจุบันอยู่ในไฟล์ส่วนหัว rtmfp.hpp
แอปพลิเคชันจะยกตัวอย่าง IPlatformAdapter และ ICryptoAdapter จากนั้น com::zenomt::rtmfp::RTMFP (ซึ่งต้องใช้อะแดปเตอร์เหล่านี้) โดยทั่วไปแล้วอะแดปเตอร์แพลตฟอร์มจะต้องได้รับการบอกเล่าของอินสแตนซ์ RTMFP ใหม่เพื่อให้สามารถเรียกใช้วิธีการแพลตฟอร์มของอินสแตนซ์ (เช่น howLongToSleep() และ onReceivePacket() )
แพลตฟอร์มจะเพิ่มอย่างน้อยหนึ่ง อินเทอร์เฟซ โดยเรียก RTMFP::addInterface()
แอปพลิเคชันสามารถเปิดการส่งกระแสไปยังจุดสิ้นสุดใหม่หรือปัจจุบันด้วย RTMFP::openFlow() และ Flow::openFlow และสามารถเปิดกระแสการส่งคืนที่เกี่ยวข้องด้วย RecvFlow::openReturnFlow()
แอปพลิเคชันสามารถรับกระแสใหม่ได้โดยการตั้งค่าการเรียกกลับ onRecvFlow บน RTMFP (สำหรับกระแสที่เข้ามา) หรือบน SendFlow S (สำหรับกระแสการส่งคืนที่เกี่ยวข้อง)
แอปพลิเคชันสามารถส่งข้อความไปยังเพื่อนที่มี SendFlow::write() และรับข้อความจากเพื่อนที่ไกลออกไปโดยการตั้งค่าการโทร onMessage บน RecvFlow s ข้อความสามารถหมดอายุและถูกทอดทิ้งหากไม่ได้เริ่มต้นหรือส่งมอบตามกำหนดเวลาตามลำดับหรือตามตรรกะแอปพลิเคชันโดยพลการโดยใช้ WriteReceipt S ที่ส่งคืนโดย SendFlow::write() แอปพลิเคชันสามารถแจ้งเตือนโดยการโทรกลับเมื่อมีการส่งข้อความหรือถูกทอดทิ้ง
SendFlow S ตั้งค่าเป็นลำดับความสำคัญ/ความสำคัญ PRI_PRIORITY , PRI_IMMEDIATE , PRI_FLASH หรือ PRI_FLASHOVERRIDE ถือว่าเป็นเวลาที่สำคัญ การส่งข้อความที่สำคัญมีผลต่อการควบคุมความแออัด
เมื่อเสร็จสิ้นแอปพลิเคชันสามารถปิด RTMFP ในลักษณะที่เป็นระเบียบหรือทันที
การใช้งานโปรโตคอลเป็นเธรดเดี่ยวและไม่มีล็อค/mutexes การโทรทั้งหมดไปยัง APIs ของมันจะต้องซิงโครไนซ์ภายนอกเช่นโดยทุกคนอยู่ในเธรดเดียวกันหรือโครงสร้างที่คล้ายกับลูป สิ่งนี้ทำเพื่อปรับปรุงการพกพาและประสิทธิภาพเนื่องจากการล็อคอาจมีราคาแพงมากในซีพียูที่ทันสมัย การซิงโครไนซ์ถูกแยกออกโดยวิธี perform ของอะแดปเตอร์แพลตฟอร์มเพื่อให้สามารถถ่ายการดำเนินงานที่มีราคาแพงหรือใช้เวลานานไปยังคอร์/เธรดอื่น ๆ หากต้องการ
การใช้งานโปรโตคอลไม่ได้โต้ตอบโดยตรงกับซ็อกเก็ต UDP ของระบบปฏิบัติการนาฬิกาเรียกใช้ลูปล็อคหรือเธรด การโต้ตอบเหล่านี้ถูกแยกออกไปยัง อะแดปเตอร์แพลตฟอร์ม ที่จัดทำโดยโปรแกรมโฮสต์
อะแดปเตอร์แพลตฟอร์ม จะเป็นการใช้งานที่เป็นรูปธรรมของ com::zenomt::rtmfp::IPlatformAdapter ที่เรียกวิธีการอินสแตนซ์สาธารณะ RTMFP ในส่วน "ใช้โดยอะแดปเตอร์แพลตฟอร์ม" อะแดปเตอร์ให้เวลาปัจจุบันการอ่านและการเขียนไปยังซ็อกเก็ตเวลาและการซิงโครไนซ์
ไลบรารีจัดเตรียมอะแดปเตอร์แพลตฟอร์มสองตัวอย่างที่ทำงานใน RunLoop S: PosixPlatformAdapter สำหรับแอปพลิเคชันแบบเธรดเดี่ยวบริสุทธิ์และ PerformerPosixPlatformAdapter เพื่อให้สามารถถ่ายภาพการเข้ารหัสลับสำคัญของ CPU อะแดปเตอร์แพลตฟอร์มเหล่านี้ควรเหมาะสำหรับแอพพลิเคชั่นจำนวนมากในระบบปฏิบัติการที่เหมือน UNIX และควรใช้เป็นตัวอย่างของวิธีการเขียนอะแดปเตอร์แพลตฟอร์มแบบหลายเธรดและแบบมัลติเธรดสำหรับแอปพลิเคชันโฮสต์ของคุณ
ไม่มีข้อกำหนดสำหรับอินเทอร์เฟซ ของอะแดปเตอร์แพลตฟอร์ม ที่จะเป็นซ็อกเก็ต UDP ตัวอย่างเช่น อินเทอร์เฟซ อาจเป็นถุงเท้าหรือเปลี่ยนพร็อกซีอุโมงค์หรือจำลองเครือข่าย
สำหรับระบบปฏิบัติการที่มีลักษณะคล้าย UNIX ไลบรารีนี้ให้ select() แบบใช้งานง่ายสำหรับแอพพลิเคชั่นที่ใช้ซ็อกเก็ตจำนวนมาก นอกจากนี้ยังมีลูปวิ่งตาม epoll อย่างง่ายสำหรับ Linux ที่ปรับขนาดได้ดีกว่า select() สำหรับการจัดการซ็อกเก็ตจำนวนมาก ใช้นามแฝง PreferredRunLoop เพื่อเลือกตัวแปรที่ดีที่สุดที่มีอยู่ในเวลาคอมไพล์โดยอัตโนมัติสำหรับระบบปฏิบัติการเป้าหมาย
Performer สามารถแนบกับลูปเรียกใช้เพื่อเปิดใช้งานการเรียกใช้งานภายใน/ซิงโครไนซ์กับลูปเรียกใช้จากเธรดใด ๆ Performer S ใช้กับ PerformerPosixPlatformAdapter
Microsoft Windows ไม่ใช่แพลตฟอร์มที่รองรับ อย่างเป็นทางการ อย่างไรก็ตามห้องสมุดหลัก (ไม่รวมอะแดปเตอร์แพลตฟอร์มเรียกใช้ลูปและ Performer ) ควรสร้างบน Windows และการบำรุงรักษาแกนกลางสำหรับแพลตฟอร์มนั้นจะถูกพยายามเป็นเวลาและความช่วยเหลือจากชุมชนอนุญาต โปรดเปิดปัญหาหากมีปัญหากับไลบรารีหลักบน Windows
ในการใช้ไลบรารีนี้บน Windows คุณจะต้องจัดหาอะแดปเตอร์แพลตฟอร์มที่เหมาะสม
โปรดติดต่อผู้ดูแลหรือเปิดปัญหาเพื่อขอลิงค์ไปยังอะแดปเตอร์แพลตฟอร์ม Windows ของคุณที่จะเพิ่มที่นี่ในเอกสารนี้
RFC 7016 อธิบายถึงกรอบทั่วไปสำหรับการรักษาความปลอดภัยการสื่อสาร RTMFP ตามความต้องการของแอปพลิเคชันและออกจากข้อมูลเฉพาะการเข้ารหัสไปยัง โปรไฟล์การเข้ารหัส ห้องสมุดนี้ไม่ได้ล็อคแอปพลิเคชันไปยังโปรไฟล์การเข้ารหัสเฉพาะใด ๆ และเขียนขึ้นเพื่อรองรับโปรไฟล์ที่มีศักยภาพมากมาย โปรไฟล์การเข้ารหัสถูกนำมาใช้โดย ICryptoAdapter คอนกรีตที่ให้กับ RTMFP ในการสร้างอินสแตนซ์
แอปพลิเคชันส่วนใหญ่ของ RTMFP จะใช้ โปรไฟล์การเข้ารหัสสำหรับการสื่อสารแฟลช ที่อธิบายไว้ใน RFC 7425 ซึ่งจัดทำโดย FlashCryptoAdapter โปรดทราบว่าอะแดปเตอร์นี้เป็นนามธรรมและจะต้องเป็นแบบย่อยเพื่อให้มีการใช้งานที่เป็นรูปธรรมของการเข้ารหัสดั้งเดิมที่จำเป็น การใช้งานที่เป็นรูปธรรมโดยใช้ OpenSSL นั้นจัดทำโดย FlashCryptoAdapter_OpenSSL ซึ่งสามารถใช้เป็นตัวอย่างสำหรับวิธีการใช้ไลบรารีการเข้ารหัสอื่น ๆ หากคุณไม่มี openssl หรือคุณไม่ต้องการใช้มันคุณสามารถระงับการสร้างโมดูลนี้ได้โดยการกำหนด make ที่ WITHOUT_OPENSSL หากการติดตั้ง OpenSSL ของคุณอยู่ด้านนอกของค่าเริ่มต้นของคอมไพเลอร์รวมถึงและเส้นทางการค้นหา linker คุณสามารถ make ตัวแปร OPENSSL_INCLUDEDIR และ OPENSSL_LIBDIR พร้อมคำสั่งที่เหมาะสม (ดูตัวอย่าง Makefile )
การใช้งาน OpenSSL ของ FlashCryptoAdapter ใช้การแลกเปลี่ยนคีย์อินเทอร์เน็ต 4096 บิต (IKE) กลุ่ม 16, 2048- บิตกลุ่มไอค์ 14 และกลุ่มไอค์ 2 1024 บิตสำหรับข้อตกลงคีย์ Diffie-Hellman การใช้งานทั้งหมดของโปรไฟล์การเข้ารหัสการสื่อสารการสื่อสารแฟลช จะต้อง ใช้อย่างน้อยกลุ่ม 2; บางคนใช้กลุ่ม 14 การใช้งานนี้ชอบกลุ่มร่วมที่แข็งแกร่งที่สุด
โปรดทราบว่า RTMFP ไม่ จำกัด เฉพาะการสื่อสารแพลตฟอร์มแฟลช ไลบรารีนี้มี PlainCryptoAdapter ที่เหมาะสำหรับการทดสอบและการประเมินผล เนื่องจากไม่มีการเข้ารหัสที่เกิดขึ้นจริง (และวิธีการ cryptoHash256() และวิธีการ pseudoRandomBytes() นั้นอ่อนแอโดยเฉพาะ) จึงไม่เหมาะสำหรับการใช้งานการผลิตในอินเทอร์เน็ตเปิด อย่า.
BufferBloat (การบัฟเฟอร์และการเข้าคิวที่มากเกินไปในเครือข่าย) อาจทำให้เกิดความล่าช้าแบบ end-to-end สูงส่งผลให้ประสิทธิภาพที่ไม่สามารถยอมรับได้สำหรับแอปพลิเคชันแบบเรียลไทม์ น่าเสียดายที่ทางออกที่ดีที่สุดสำหรับปัญหานี้ (การจัดการคิวที่ใช้งานด้วยการแจ้งเตือนความแออัดที่ชัดเจน) ไม่ได้ถูกนำไปใช้ในระดับสากลในอินเทอร์เน็ตในเวลานี้
นอกเหนือจากสัญญาณความแออัดปกติ (การสูญเสียและการแจ้งเตือนความแออัดที่ชัดเจน) ไลบรารีนี้สามารถเลือกได้โดยมีความแออัดที่น่าจะเป็นไปได้ในเซสชั่นจากการเพิ่มเวลาในการเดินทางไปกลับ (RTT) ในการเปิดใช้งานความสามารถนี้ให้ใช้ Flow::setSessionCongestionDelay() เพื่อกำหนดจำนวนความล่าช้าเพิ่มเติมเหนือ RTT พื้นฐานที่จะตีความว่าเป็นข้อบ่งชี้ของความแออัด ค่าเริ่มต้นคือ INFINITY แนะนำให้มีค่าความล่าช้าเพิ่มเติม 0.1 วินาทีสำหรับคุณลักษณะนี้
RTT พื้นฐานคือ RTT ขั้นต่ำที่สังเกตได้มากที่สุดในช่วงสามนาทีที่ผ่านมา หน้าต่างการสังเกต RTT พื้นฐานจะถูกล้างและรีเซ็ตในสถานการณ์ต่อไปนี้:
จากเวลาเป็นครั้งคราวหากมีการใช้หน้าต่างความแออัดที่สำคัญหน้าต่างความแออัดจะลดลงชั่วคราวเพื่อตรวจสอบเส้นทางสำหรับ RTT พื้นฐานใหม่ (ในกรณีที่การส่งของเราเองเป็นการปิดบังพื้นฐาน) โปรดทราบว่าสิ่งนี้อาจทำให้เกิดความกระวนกระวายใจ
หาก RTT ที่ราบรื่นถูกสังเกตว่าอยู่เหนือระดับพื้นฐานรวมถึง CongestionDelay ที่กำหนดค่า (และยังมีอย่างน้อย 30ms) นี่จะถือว่าเป็นข้อบ่งชี้ของความแออัด คอนโทรลเลอร์ความแออัดตอบสนองต่อสิ่งนี้ราวกับว่ามันเป็นการสูญเสีย
รูปแบบการตรวจจับความแออัดนี้เช่นเดียวกับแผนการล่าช้าแบบ end-to-end ทั้งหมดนั้นไม่สมบูรณ์และอยู่ภายใต้สัญญาณบวกเท็จที่เกิดจากกรณีรวมถึง:
ดังนั้นคุณสมบัตินี้อาจไม่ได้ระบุไว้สำหรับกรณีการใช้งานทั้งหมด ควรใช้ความระมัดระวังเพื่อเปิดใช้งานคุณสมบัตินี้เฉพาะเมื่อสัญญาณความแออัดที่เป็นบวกผิดพลาดนั้นไม่น่าเป็นไปได้เช่นการส่งผ่านสื่อเดียวอย่างมีนัยสำคัญผ่านคอขวดเฉพาะ ผลบวกที่ผิดพลาดอาจทำให้เกิดความอดอยากในการส่งผ่าน
คุณลักษณะนี้ได้รับแรงบันดาลใจจากการขนส่งพื้นหลังการหน่วงเวลาพิเศษต่ำ (LEDBAT) การปรับอัตราการปิดกั้นตนเองสำหรับมัลติมีเดีย (SCREAM) และอัลกอริทึมการควบคุมความแออัดของ BBR ของ Google
การใช้ RTMFP นี้เพิ่มการสนับสนุนสำหรับการแจ้งเตือนความแออัดที่ชัดเจน (ECN) มันเพิ่ม“ รายงาน ECN” (Type 0xec ) ใหม่เพื่อให้ผู้รับส่งจำนวน ECN codepoints ที่ได้รับกลับไปยังผู้ส่ง ECN RTMFP จะต้องไม่ ส่งรายงาน ECN ไปยังเพียร์เว้นแต่ว่าจะได้รับแพ็กเก็ตที่ถูกต้องอย่างน้อยหนึ่งชุดในเซสชั่น S_OPEN กับเพียร์ที่ทำเครื่องหมายด้วยจุดรหัสการขนส่งที่มีความสามารถ ECN ( ECT(0) , ECT(1) หรือ ECN-CE )
ตัวรับสัญญาณ RTMFP ที่สามารถส่งรายงาน ECN ได้ไปยังเพียร์ที่มีความสามารถ ECN ควร รวบรวมรายงาน ECN ก่อนที่จะได้รับการตอบรับครั้งแรกในแพ็คเก็ตใด ๆ ที่มีการรับทราบ (เพื่อหลีกเลี่ยงการตัดทอนรายงาน) เพื่อให้ผู้ส่ง ECN สามารถตรวจจับได้ว่าอินเตอร์เฟสใกล้และไกลระยะไกลเส้นทางและตัวรับการสนับสนุน ECN ตัวรับสัญญาณ ECN ควร ส่งรายงาน ECN ในแพ็คเก็ตใด ๆ ที่มีการรับทราบหากมีการส่งแพ็กเก็ตใด ๆ
ผู้ส่ง RTMFP จะต้อง หยุดการทำเครื่องหมายแพ็คเก็ตด้วยจุดรหัสการขนส่งที่มีความสามารถ ECN หากกำหนดว่าตัวรับสัญญาณไม่สามารถใช้งานได้ ECN (ตัวอย่างเช่นหากผู้ส่งไม่ได้รับรายงาน ECN อย่างน้อยหนึ่งฉบับพร้อมกับการรับทราบข้อมูลผู้ใช้ที่ส่งในแพ็กเก็ตที่ทำเครื่องหมายไว้
ตัวรับสัญญาณ RTMFP ที่มีความสามารถ ECN ช่วยรักษาจำนวนแพ็กเก็ตที่ได้รับอย่างน้อยที่สุดไว้ด้วย ECN-CE จุดสิ้นสุดส่ง 8 บิตต่ำของตัวนับปัจจุบันไปยังเพียร์ในรายงาน ECN รายงาน
การใช้งานนี้ส่ง ECT(0) คอนโทรลเลอร์ความแออัดตอบสนองต่อการเพิ่มขึ้นของ ECN-CE-count ราวกับว่ามันเป็นการสูญเสีย ECT(0) จะส่งเฉพาะแพ็คเก็ตที่มีข้อมูลผู้ใช้
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0xec | 1 | ECN-CE-count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
struct ecnReportChunkPayload_t
{
uint8_t congestionExperiencedCountMod256; // ECN-CE-count
} :8;
congestionExperiencedCountMod256 : จำนวนแพ็คเก็ตที่ได้รับ 8 บิตต่ำที่ได้รับจากเพียร์ที่ทำเครื่องหมายด้วย ECN-CE (ECN congestion ประสบการณ์)