การส่งข้อมูลระหว่างเบราว์เซอร์ 2 เบราว์เซอร์เพื่อการสื่อสาร การเล่นเกม หรือการโอนไฟล์อาจเป็นกระบวนการที่ค่อนข้างเกี่ยวข้อง จะต้องมีการตั้งค่าและจ่ายเงินเพื่อให้เซิร์ฟเวอร์ในการส่งต่อข้อมูล และอาจปรับขนาดนี้ไปยังศูนย์ข้อมูลหลายแห่ง ในสถานการณ์นี้ อาจมีเวลาในการตอบสนองสูงและเก็บรักษาข้อมูลให้เป็นส่วนตัวได้ยาก
ปัญหาเหล่านี้บรรเทาได้โดยใช้ RTCDataChannel
API ของ WebRTC เพื่อโอนข้อมูลจากเครื่องหนึ่งไปยังอีกเครื่องหนึ่งโดยตรง บทความนี้ครอบคลุมพื้นฐานวิธีตั้งค่าและใช้ช่องทางข้อมูล รวมถึงกรณีการใช้งานทั่วไปบนเว็บในปัจจุบัน
สาเหตุที่ควรใช้ช่องทางข้อมูลอื่น
เรามี WebSocket, AJAX และ เหตุการณ์ที่ส่งของเซิร์ฟเวอร์ ทำไมเราถึงต้องมีช่องทางการสื่อสารอื่นด้วย WebSocket เป็นแบบสองทิศทาง แต่เทคโนโลยีเหล่านี้ทั้งหมดได้รับการออกแบบมาเพื่อการสื่อสารระหว่างหรือจากเซิร์ฟเวอร์
RTCDataChannel
ใช้วิธีอื่น
- ฟีเจอร์นี้ใช้งานได้กับ
RTCPeerConnection
API ซึ่งช่วยให้เชื่อมต่อแบบเพียร์ทูเพียร์ได้ ซึ่งอาจส่งผลให้เวลาในการตอบสนองต่ำลง - ไม่มีเซิร์ฟเวอร์ตัวกลาง และมี "รอบ" น้อยลง RTCDataChannel
ใช้ Stream Control TExport Protocol (SCTP) ช่วยให้นำส่งการกำหนดค่าการนำส่งนอกการสั่งซื้อได้และนำส่งการกำหนดค่าได้
RTCDataChannel
พร้อมให้บริการแล้วด้วยการรองรับ SCTP ในเดสก์ท็อปและ Android ใน Google Chrome, Opera และ Firefox
ข้อควรระวัง: การส่งสัญญาณ, STUN และ TURN
WebRTC เปิดใช้การสื่อสารแบบเพียร์ทูเพียร์ แต่ยังต้องการเซิร์ฟเวอร์สำหรับการส่งสัญญาณเพื่อแลกเปลี่ยนสื่อและข้อมูลเมตาของเครือข่ายเพื่อเปิดการเชื่อมต่อแบบเพียร์
WebRTC จะทำงานร่วมกับ NAT และไฟร์วอลล์ด้วยสิ่งต่อไปนี้
- เฟรมเวิร์ก ICE เพื่อสร้างเส้นทางเครือข่ายที่ดีที่สุดระหว่างแอปเทียบเท่า
- เซิร์ฟเวอร์ STUN เพื่อค้นหา IP และพอร์ตที่เข้าถึงได้แบบสาธารณะสำหรับแต่ละเพียร์
- ปิดเซิร์ฟเวอร์ หากการเชื่อมต่อโดยตรงไม่สำเร็จและต้องมีการส่งต่อข้อมูล
โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ WebRTC ทำงานร่วมกับเซิร์ฟเวอร์สำหรับการส่งสัญญาณและการสร้างเครือข่ายที่หัวข้อ WebRTC ในชีวิตจริง: STUN, TURN และการส่งสัญญาณ
ความสามารถ
RTCDataChannel
API รองรับชุดข้อมูลประเภทที่ยืดหยุ่น API นี้ออกแบบมาให้เลียนแบบ WebSocket ทุกประการ และ RTCDataChannel
รองรับสตริง รวมถึงไบนารีบางประเภทใน JavaScript เช่น Blob, ArrayBuffer และ ArrayBufferView ประเภทดังกล่าวจะมีประโยชน์เมื่อต้องโอนไฟล์และเล่นเกมแบบผู้เล่นหลายคน
RTCDataChannel
อาจทำงานในโหมดที่ไม่น่าเชื่อถือและไม่มีลำดับ (คล้ายกับโปรโตคอล User Datagram หรือ UDP), โหมดที่เชื่อถือได้และสั่งซื้อ (คล้ายกับ TExport Control Protocol หรือ TCP) และโหมดที่เชื่อถือได้บางส่วน ดังนี้
- โหมดที่มีลำดับและความน่าเชื่อถือจะรับประกันการส่งข้อความและลำดับการส่งข้อความ การดำเนินการนี้ต้องใช้ค่าใช้จ่ายเพิ่มเติม จึงอาจทำให้โหมดนี้ทำงานช้าลงได้
- โหมดที่ไม่น่าเชื่อถือและไม่ได้เรียงลำดับไม่ได้รับประกันว่าข้อความทั้งหมดจะไปถึงอีกฝั่งหนึ่งหรือไปถึงลำดับใดก็ตาม ซึ่งจะนำส่วนเกินออกและช่วยให้โหมดนี้ทำงานได้เร็วขึ้นมาก
- โหมดที่เชื่อถือได้บางส่วนจะรับประกันการส่งข้อความภายใต้เงื่อนไขบางอย่าง เช่น การหมดเวลาในการส่งหรือการส่งซ้ำเป็นจำนวนครั้งสูงสุด นอกจากนี้ยังสามารถกำหนดค่าการจัดลำดับข้อความได้ด้วย
ประสิทธิภาพของ 2 โหมดแรกจะเท่ากันเมื่อไม่สูญเสียแพ็กเก็ต อย่างไรก็ตาม ในโหมดที่เสถียรและสั่งซื้อได้ แพ็กเก็ตที่สูญหายจะทำให้แพ็กเก็ตอื่นๆ ตามหลังแพ็กเก็ตนั้นหายไป และแพ็กเก็ตที่สูญหายอาจไม่อัปเดตเมื่อมีการส่งแพ็กเก็ตอีกครั้งและมาถึงแล้ว แน่นอนว่ามีความเป็นไปได้ในการใช้ช่องทางข้อมูลหลายๆ ช่องทางภายในแอปเดียวกัน โดยแต่ละช่องทางมีความหมายที่เชื่อถือได้หรือเชื่อถือไม่ได้
ตารางที่เป็นประโยชน์จากเครือข่ายเบราว์เซอร์ประสิทธิภาพสูงโดย Ilya Grigorik
TCP | UDP | SCTP | |
ความน่าเชื่อถือ | เชื่อถือได้ | ไม่น่าเชื่อถือ | กำหนดค่าได้ |
บริการจัดส่ง | สั่งอาหารแล้ว | ไม่เรียงลำดับ | กำหนดค่าได้ |
การส่งข้อมูล | ตามไบต์ | เน้นข้อความ | เน้นข้อความ |
การควบคุมการรับส่งข้อมูล | ใช่ | ไม่ได้ | ใช่ |
การควบคุมความคับคั่ง | ใช่ | ไม่ได้ | ใช่ |
ถัดไป คุณจะได้เรียนรู้วิธีกําหนดค่า RTCDataChannel
เพื่อให้ใช้โหมดที่เชื่อถือได้ และมีลำดับ หรือไม่น่าเชื่อถือและไม่เป็นไปตามลำดับ
การกำหนดค่าแชแนลข้อมูล
การสาธิต RTCDataChannel
ออนไลน์แบบง่ายๆ มีดังนี้
ในตัวอย่างเหล่านี้ เบราว์เซอร์จะสร้างการเชื่อมต่อแบบเพียร์กับตัวเอง จากนั้นจึงสร้างแชแนลข้อมูลและส่งข้อความผ่านการเชื่อมต่อแบบเพียร์ จากนั้นจึงสร้างช่องทางข้อมูลและส่งข้อความผ่านการเชื่อมต่อแบบเพียร์ ในที่สุด ข้อความของคุณก็จะปรากฏในช่องในอีกด้านหนึ่งของหน้าเว็บ
รหัสสำหรับการเริ่มต้นใช้งานมีอธิบายสั้นๆ ดังนี้
const peerConnection = new RTCPeerConnection();
// Establish your peer connection using your signaling channel here
const dataChannel =
peerConnection.createDataChannel("myLabel", dataChannelOptions);
dataChannel.onerror = (error) => {
console.log("Data Channel Error:", error);
};
dataChannel.onmessage = (event) => {
console.log("Got Data Channel Message:", event.data);
};
dataChannel.onopen = () => {
dataChannel.send("Hello World!");
};
dataChannel.onclose = () => {
console.log("The Data Channel is Closed");
};
ออบเจ็กต์ dataChannel
สร้างขึ้นจากการเชื่อมต่อเพียร์ที่สร้างไว้แล้ว โดยสามารถสร้างก่อนหรือหลังการส่งสัญญาณได้ จากนั้นคุณจะส่งป้ายกำกับเพื่อแยกช่องนี้ออกจากช่องอื่นๆ และชุดการตั้งค่าที่ไม่บังคับซึ่งได้แก่
const dataChannelOptions = {
ordered: false, // do not guarantee order
maxPacketLifeTime: 3000, // in milliseconds
};
คุณยังเพิ่มตัวเลือก maxRetransmits
ได้ด้วย (จำนวนครั้งที่ต้องลองก่อนล้มเหลว) แต่จะระบุ maxRetransmits หรือ maxPacketLifeTime อย่างใดอย่างหนึ่งไม่ได้ สำหรับความหมายของ UDP ให้ตั้งค่า maxRetransmits
เป็น 0
และ ordered
เป็น false
ดูข้อมูลเพิ่มเติมได้ที่ IETF RFCs ต่อไปนี้ Stream Control Tunction Protocol และ Stream Control TExport Protocol Fully Reliability Extension
ordered
: ช่องทางข้อมูลควรรับประกันการสั่งซื้อหรือไม่maxPacketLifeTime
: เวลาสูงสุดในการพยายามส่งข้อความที่ล้มเหลวอีกครั้งmaxRetransmits
: จำนวนครั้งสูงสุดในการพยายามส่งข้อความที่ล้มเหลวอีกครั้งprotocol
: อนุญาตให้ใช้โปรโตคอลย่อยที่ระบุข้อมูลเมตาเกี่ยวกับแอปnegotiated
: หากตั้งค่าเป็น "จริง" จะนำการตั้งค่าอัตโนมัติของช่องทางข้อมูลในอีกเครือข่ายหนึ่งออกเพื่อกำหนดช่องทางข้อมูลของคุณเองด้วยรหัสเดียวกันในอีกฝั่งหนึ่งid
: ให้คุณระบุรหัสของคุณเองสำหรับช่องซึ่งสามารถใช้ร่วมกับnegotiated
ที่ตั้งค่าเป็นtrue
เท่านั้น)
ตัวเลือกเดียวที่ผู้คนส่วนใหญ่ต้องใช้คือ 3 ตัวเลือกแรก ได้แก่ ordered
, maxPacketLifeTime
และ maxRetransmits
เมื่อมี SCTP (ขณะนี้ใช้โดยเบราว์เซอร์ทั้งหมดที่รองรับ WebRTC) เชื่อถือได้และมีการสั่งซื้อเป็น "จริง" โดยค่าเริ่มต้น คุณควรใช้ความเสถียรและไม่เรียงลำดับหากต้องการการควบคุมจากเลเยอร์แอปอย่างเต็มที่ แต่ในกรณีส่วนใหญ่ ความเสถียรบางส่วนจะเป็นประโยชน์
โปรดทราบว่า เช่นเดียวกับ WebSocket RTCDataChannel
จะเริ่มเหตุการณ์เมื่อมีการสร้างการเชื่อมต่อ ปิด หรือเกิดข้อผิดพลาด และเมื่อได้รับข้อความจากเพียร์อื่น เช่นเดียวกับ WebSocket
เทรนด์หรือชาเลนจ์นี้ปลอดภัยไหม
คอมโพเนนต์ WebRTC ทั้งหมดจำเป็นต้องมีการเข้ารหัส เมื่อใช้ RTCDataChannel
ข้อมูลทั้งหมดจะปลอดภัยด้วย Datagram Transport Layer Security (DTLS) DTLS เป็นอนุพันธ์ของ SSL ซึ่งหมายความว่าข้อมูลของคุณจะมีความปลอดภัยเหมือนกับการใช้การเชื่อมต่อแบบ SSL มาตรฐาน DTLS ได้รับมาตรฐานและมีอยู่ในเบราว์เซอร์ทั้งหมดที่รองรับ WebRTC ดูข้อมูลเพิ่มเติมได้ใน Wireshark wiki
เปลี่ยนวิธีคิดเกี่ยวกับข้อมูล
การจัดการข้อมูลจำนวนมากอาจเป็นปัญหาใน JavaScript ดังที่นักพัฒนาซอฟต์แวร์ของ Sharefest ได้อธิบายไว้ กระบวนการนี้จำเป็นต้องคำนึงถึงข้อมูลในรูปแบบใหม่ หากคุณกำลังโอนไฟล์ที่มีขนาดใหญ่กว่าหน่วยความจำที่มี คุณต้องคิดหาวิธีใหม่ๆ ในการบันทึกข้อมูลนี้ และนี่คือจุดที่เทคโนโลยีต่างๆ เช่น FileSystem API จะเข้ามามีบทบาท
สร้างแอปสำหรับแชร์ไฟล์
คุณสร้างเว็บแอปที่แชร์ไฟล์ในเบราว์เซอร์ได้แล้วด้วย RTCDataChannel
การสร้างต่อยอด RTCDataChannel
หมายความว่าข้อมูลไฟล์ที่โอนจะได้รับการเข้ารหัสและไม่กระทบกับเซิร์ฟเวอร์ของผู้ให้บริการแอป ฟังก์ชันนี้ประกอบกับความสามารถในการเชื่อมต่อกับไคลเอ็นต์หลายตัวเพื่อการแชร์ที่รวดเร็วขึ้น ทำให้การแชร์ไฟล์ WebRTC เป็นตัวเลือกที่ดีสำหรับเว็บ
การดำเนินการโอนสำเร็จมีดังนี้
- อ่านไฟล์ใน JavaScript โดยใช้ File API
- เชื่อมต่อแบบเพียร์ระหว่างไคลเอ็นต์ด้วย
RTCPeerConnection
- สร้างแชแนลข้อมูลระหว่างไคลเอ็นต์ด้วย
RTCDataChannel
สิ่งที่ควรพิจารณาเมื่อพยายามส่งไฟล์เกิน RTCDataChannel
มีดังนี้
- ขนาดไฟล์: หากไฟล์มีขนาดเล็กพอสมควรและสามารถจัดเก็บและโหลดเป็น Blob เดียวได้ คุณสามารถโหลดลงในหน่วยความจำโดยใช้ File API แล้วส่งไฟล์ไปยังช่องทางที่เชื่อถือได้ตามที่เป็นอยู่ (แต่โปรดทราบว่าเบราว์เซอร์จะกำหนดขีดจำกัดขนาดการโอนสูงสุด) เมื่อไฟล์มีขนาดใหญ่ขึ้น สิ่งต่างๆ ก็จะซับซ้อนขึ้น เมื่อต้องใช้กลไกการแบ่งส่วน ระบบจะโหลดชิ้นส่วนไฟล์และส่งไปยังเพียร์รายอื่น พร้อมด้วยข้อมูลเมตา
chunkID
เพื่อให้เพียร์จดจำได้ โปรดทราบว่าในกรณีนี้ คุณจะต้องบันทึกส่วนดังกล่าวลงในพื้นที่เก็บข้อมูลออฟไลน์ก่อน (เช่น การใช้ FileSystem API) แล้วบันทึกลงในดิสก์ของผู้ใช้ต่อเมื่อคุณมีไฟล์ครบถ้วนเท่านั้น - ขนาดกลุ่ม: ข้อมูลเหล่านี้คือ "ขนาดเล็ก" ที่เล็กที่สุดสำหรับแอปของคุณ คุณจำเป็นต้องแบ่งเป็นส่วนย่อยๆ เนื่องจากขณะนี้มีการจำกัดขนาดการส่ง (แต่จะแก้ไขในแชแนลข้อมูลเวอร์ชันในอนาคต) คำแนะนำปัจจุบันสำหรับขนาดกลุ่มสูงสุดคือ 64 KiB
เมื่อโอนไฟล์ไปยังอีกฝั่งหนึ่งเสร็จสมบูรณ์แล้ว คุณจะดาวน์โหลดไฟล์ได้โดยใช้แท็ก Anchor ดังนี้
function saveFile(blob) {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'File Name';
link.click();
};
แอปแชร์ไฟล์เหล่านี้ใน PubShare และ GitHub ใช้เทคนิคนี้ โซลูชันเหล่านี้เป็นโอเพนซอร์สและเป็นรากฐานที่ดีสำหรับแอปแชร์ไฟล์ตาม RTCDataChannel
แล้วคุณทำอะไรได้บ้าง
RTCDataChannel
เปิดประตูสู่วิธีใหม่ๆ ในการสร้างแอปสำหรับการแชร์ไฟล์ การเล่นเกมแบบผู้เล่นหลายคน และการนำส่งเนื้อหา
- การแชร์ไฟล์แบบเพียร์ทูเพียร์ตามที่อธิบายไว้ก่อนหน้านี้
- การเล่นเกมแบบผู้เล่นหลายคนพร้อมด้วยเทคโนโลยีอื่นๆ เช่น WebGL ดังที่เห็นใน BananaBread ของ Mozilla
- การส่งเนื้อหาได้รับการคิดค้นขึ้นใหม่โดย PeerCDN ซึ่งเป็นเฟรมเวิร์กที่ส่งเนื้อหาเว็บผ่านการสื่อสารข้อมูลแบบเพียร์ทูเพียร์
เปลี่ยนวิธีสร้างแอป
ตอนนี้คุณให้บริการแอปที่น่าสนใจมากขึ้นได้แล้วโดยใช้การเชื่อมต่อประสิทธิภาพสูงและเวลาในการตอบสนองต่ำผ่าน RTCDataChannel
เฟรมเวิร์ก เช่น PeerJS และ PubNub WebRTC SDK ช่วยให้ RTCDataChannel
ติดตั้งใช้งานได้ง่ายขึ้น นอกจากนี้ API ยังรองรับการใช้งานในวงกว้างบนแพลตฟอร์มต่างๆ
การถือกำเนิดของ RTCDataChannel
อาจเปลี่ยนมุมมองที่คุณมีต่อการโอนข้อมูลในเบราว์เซอร์