การส่งข้อมูลระหว่างเบราว์เซอร์ 2 ตัวเพื่อการสื่อสาร เล่นเกม หรือการโอนไฟล์อาจเป็นกระบวนการที่ค่อนข้างซับซ้อน จำเป็นต้องใช้การตั้งค่าและจ่ายเงินเพื่อให้เซิร์ฟเวอร์ส่งต่อข้อมูล และอาจปรับขนาดไปยังศูนย์ข้อมูลหลายแห่ง ในกรณีนี้ อาจมีเวลาในการตอบสนองสูงและรักษาข้อมูลให้เป็นส่วนตัวได้ยาก
ปัญหาเหล่านี้ลดได้โดยใช้ RTCDataChannel
API ของ WebRTC เพื่อโอนข้อมูลจากเครื่องหนึ่งไปยังอีกเครื่องหนึ่งโดยตรง บทความนี้ครอบคลุมพื้นฐานเกี่ยวกับวิธีตั้งค่าและใช้แชแนลข้อมูล รวมถึงกรณีการใช้งานที่พบบ่อยบนเว็บในปัจจุบัน
เหตุใดจึงต้องมีช่องทางข้อมูลอีกช่องทางหนึ่ง
เรามี WebSocket, AJAX และ Server Sent Events เหตุใดเราจึงต้องใช้ช่องทางการสื่อสารอีกช่องทางหนึ่ง WebSocket เป็นการสื่อสารแบบ 2 ทิศทาง แต่เทคโนโลยีเหล่านี้ทั้งหมดออกแบบมาเพื่อการสื่อสารกับหรือจากเซิร์ฟเวอร์
RTCDataChannel
ใช้แนวทางที่ต่างออกไป ดังนี้
- โดยสามารถใช้งานร่วมกับ
RTCPeerConnection
API ซึ่งเปิดใช้การเชื่อมต่อแบบ peer-to-peer ซึ่งอาจส่งผลให้เวลาในการตอบสนองลดลง เนื่องจากไม่มีเซิร์ฟเวอร์สื่อกลางและ "Hop" น้อยลง RTCDataChannel
ใช้ Stream Control Transmission Protocol (SCTP) ซึ่งช่วยให้สามารถกำหนดค่าการส่งออกตามความหมายที่ไม่เป็นระเบียบและกำหนดค่าการส่งอีกครั้งได้
RTCDataChannel
พร้อมให้ใช้งานแล้วใน Google Chrome, Opera และ Firefox บนเดสก์ท็อปและ Android โดยรองรับ SCTP
ข้อควรระวัง: การส่งสัญญาณ, STUN และ TURN
WebRTC จะเปิดใช้การสื่อสารแบบเพียร์ทูเพียร์ แต่ยังคงต้องการเซิร์ฟเวอร์สำหรับการส่งสัญญาณเพื่อแลกเปลี่ยนข้อมูลเมตาของสื่อและเครือข่ายเพื่อเปิดเครื่องการเชื่อมต่อแบบเพียร์
WebRTC จัดการกับ NAT และไฟร์วอลล์ด้วยวิธีต่อไปนี้
- เฟรมเวิร์ก ICE เพื่อสร้างเส้นทางเครือข่ายที่ดีที่สุดระหว่างคู่สนทนา
- เซิร์ฟเวอร์ STUN เพื่อระบุ IP และพอร์ตที่เข้าถึงได้แบบสาธารณะสำหรับแต่ละเพียร์
- เซิร์ฟเวอร์ TURN หากการเชื่อมต่อโดยตรงไม่สำเร็จและจำเป็นต้องมีการส่งต่อข้อมูล
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ WebRTC ทำงานร่วมกับเซิร์ฟเวอร์เพื่อส่งสัญญาณและเชื่อมต่อเครือข่ายได้ที่ WebRTC ในชีวิตจริง: STUN, TURN และการส่งสัญญาณ
ความสามารถ
RTCDataChannel
API รองรับชุดประเภทข้อมูลที่ยืดหยุ่น API นี้ออกแบบมาให้เลียนแบบ WebSocket ทุกประการ และ RTCDataChannel
รองรับสตริง รวมถึงไบนารีบางประเภทใน JavaScript เช่น Blob, ArrayBuffer และ ArrayBufferView ประเภทเหล่านี้มีประโยชน์เมื่อทำงานกับการโอนไฟล์และการเล่นเกมแบบหลายผู้เล่น
RTCDataChannel
สามารถทํางานในโหมดที่ไม่เสถียรและไม่เป็นระเบียบ (คล้ายกับ User Datagram Protocol หรือ UDP) โหมดที่เสถียรและเป็นระเบียบ (คล้ายกับ Transmission Control Protocol หรือ TCP) และโหมดที่เสถียรบางส่วน ดังนี้
- โหมดที่เชื่อถือได้และเป็นไปตามลําดับจะรับประกันการส่งข้อความและลําดับที่ส่งข้อความ ระบบนี้ต้องใช้ค่าใช้จ่ายในการดำเนินการเพิ่มเติม ซึ่งอาจทำให้โหมดนี้ทำงานช้าลง
- โหมดที่ไม่น่าเชื่อถือและไม่เรียงลำดับไม่ได้รับประกันว่าทุกข้อความจะส่งไปยังอีกฝ่ายหนึ่งหรือไม่ได้อยู่ในลำดับใด ซึ่งจะช่วยลดภาระงาน ทำให้โหมดนี้ทำงานได้เร็วขึ้นมาก
- โหมดที่เชื่อถือได้บางส่วนรับประกันการส่งข้อความภายใต้เงื่อนไขที่เฉพาะเจาะจง เช่น การหมดเวลาส่งใหม่หรือจำนวนการส่งใหม่สูงสุด นอกจากนี้ คุณยังกำหนดลำดับของข้อความได้ด้วย
ประสิทธิภาพของ 2 โหมดแรกจะใกล้เคียงกันเมื่อไม่มีแพ็กเก็ตสูญหาย อย่างไรก็ตาม ในโหมดที่เชื่อถือได้และจัดเรียงแล้ว แพ็กเก็ตที่สูญหายจะทำให้แพ็กเก็ตอื่นๆ ที่อยู่ข้างหลังถูกบล็อก และแพ็กเก็ตที่สูญหายอาจล้าสมัยเมื่อมีการส่งใหม่และมาถึง แน่นอนว่าคุณใช้ช่องทางข้อมูลหลายช่องทางภายในแอปเดียวกันได้ โดยแต่ละช่องทางจะมีความหมายที่เชื่อถือได้หรือไม่เชื่อถือได้
นี่คือตารางที่มีประโยชน์จากเครือข่ายเบราว์เซอร์ประสิทธิภาพสูงโดย Ilya Grigorik
TCP | UDP | SCTP | |
ความน่าเชื่อถือ | เชื่อถือได้ | ไม่น่าเชื่อถือ | กำหนดค่าได้ |
บริการจัดส่ง | ตามลำดับ | ไม่เรียงลำดับ | กำหนดค่าได้ |
ชุดเกียร์ | มุ่งเน้นที่ไบต์ | เน้นข้อความ | เน้นข้อความ |
การควบคุมโฟลว์ | ใช่ | ไม่ได้ | ใช่ |
การควบคุมการจราจร | ใช่ | ไม่ได้ | ใช่ |
ถัดไป คุณจะได้ดูวิธีกำหนดค่า RTCDataChannel
ให้ใช้โหมดที่เชื่อถือได้และมีลําดับหรือโหมดที่ไม่น่าเชื่อถือและไม่มีลําดับ
การกำหนดค่าแชแนลข้อมูล
คุณสามารถดูการสาธิต RTCDataChannel
ง่ายๆ หลายรายการทางออนไลน์ได้ ดังนี้
ในตัวอย่างเหล่านี้ เบราว์เซอร์จะสร้างการเชื่อมต่อแบบ Peer กับตัวเอง จากนั้นสร้างแชแนลข้อมูลและส่งข้อความผ่านการเชื่อมต่อแบบ Peer จากนั้นจะสร้างช่องทางข้อมูลและส่งข้อความไปตามการเชื่อมต่อแบบ Peer สุดท้าย ข้อความของคุณจะปรากฏในช่องอีกฝั่งหนึ่งของหน้า
โค้ดสั้นๆ สำหรับการเริ่มต้นใช้งานมีดังนี้
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
สร้างขึ้นจากการเชื่อมต่อแบบ Peer ที่สร้างขึ้นแล้ว โดยอาจสร้างขึ้นก่อนหรือหลังการส่งสัญญาณ จากนั้นส่งป้ายกํากับเพื่อแยกช่องนี้ออกจากช่องอื่นๆ และชุดการตั้งค่าการกําหนดค่าที่ไม่บังคับ
const dataChannelOptions = {
ordered: false, // do not guarantee order
maxPacketLifeTime: 3000, // in milliseconds
};
นอกจากนี้ คุณยังเพิ่มตัวเลือก maxRetransmits
(จำนวนครั้งที่จะลองส่งก่อนที่จะไม่สำเร็จ) ได้ แต่คุณจะระบุได้เพียง maxRetransmits หรือ maxPacketLifeTime เท่านั้น สำหรับความหมายของ UDP ให้ตั้งค่า maxRetransmits
เป็น 0
และ ordered
เป็น false
ดูข้อมูลเพิ่มเติมได้ที่ RFC ของ IETF ต่อไปนี้ Stream Control Transmission Protocol และ Stream Control Transmission Protocol Partial Reliability Extension
ordered
: ระบุว่าช่องทางข้อมูลควรรับประกันคำสั่งซื้อหรือไม่maxPacketLifeTime
: เวลาสูงสุดในการพยายามส่งข้อความที่ส่งไม่สำเร็จอีกครั้งmaxRetransmits
: จำนวนครั้งสูงสุดในการพยายามส่งข้อความที่ไม่สำเร็จอีกครั้งprotocol
: อนุญาตให้ใช้โปรโตคอลย่อย ซึ่งให้ข้อมูลเมตาแก่แอปnegotiated
: หากตั้งค่าเป็น "จริง" ระบบจะนำการตั้งค่าช่องทางข้อมูลในอีกฝั่งหนึ่งโดยอัตโนมัติออก ซึ่งจะเป็นการสร้างช่องทางข้อมูลที่มีรหัสเดียวกันในอีกฝั่งด้วยวิธีของคุณเองid
: อนุญาตให้คุณระบุรหัสของคุณเองสำหรับช่องที่สามารถใช้ร่วมกับการตั้งค่าnegotiated
เป็นtrue
เท่านั้น)
ตัวเลือกเดียวที่ผู้ใช้ส่วนใหญ่ต้องใช้คือ 3 รายการแรก ได้แก่ ordered
, maxPacketLifeTime
และ maxRetransmits
เมื่อใช้ SCTP (ปัจจุบันเบราว์เซอร์ทั้งหมดที่รองรับ WebRTC ใช้ SCTP) ค่าน่าเชื่อถือและจัดเรียงจะตั้งค่าเป็น "จริง" โดยค่าเริ่มต้น คุณควรใช้การค้นหาที่ไม่เชื่อถือและไม่เป็นระเบียบหากต้องการควบคุมจากเลเยอร์แอปโดยสมบูรณ์ แต่ในกรณีส่วนใหญ่ การค้นหาที่เชื่อถือได้บางส่วนจะมีประโยชน์
โปรดทราบว่า 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
- สร้างการเชื่อมต่อแบบ Peer ระหว่างไคลเอ็นต์ด้วย
RTCPeerConnection
- สร้างช่องทางข้อมูลระหว่างไคลเอ็นต์ด้วย
RTCDataChannel
สิ่งที่ควรพิจารณาเมื่อพยายามส่งไฟล์ผ่าน RTCDataChannel
มีดังนี้
- ขนาดไฟล์: หากไฟล์มีขนาดเล็กพอและจัดเก็บและโหลดเป็น Blob รายการเดียวได้ คุณสามารถโหลดลงในหน่วยความจําโดยใช้ File API แล้วส่งไฟล์ผ่านช่องทางที่เชื่อถือได้ตามที่เป็นอยู่ (แต่โปรดทราบว่าเบราว์เซอร์จะจํากัดขนาดการโอนสูงสุด) ยิ่งไฟล์มีขนาดใหญ่ขึ้น การดำเนินการก็จะยิ่งยากขึ้น เมื่อต้องมีกลไกการแบ่งส่วน ระบบจะโหลดกลุ่มไฟล์และส่งไปยังแอปเทียบเท่าอีกเครื่องหนึ่ง พร้อมด้วยข้อมูลเมตา
chunkID
เพื่อให้แอปเทียบเท่าจดจำได้ โปรดทราบว่าในกรณีนี้ คุณจะต้องบันทึกกลุ่มลงในพื้นที่เก็บข้อมูลออฟไลน์ก่อน (เช่น ใช้ FileSystem API) และบันทึกลงในดิสก์ของผู้ใช้เฉพาะเมื่อคุณมีไฟล์ครบถ้วนสมบูรณ์เท่านั้น - ขนาดกลุ่ม: "อะตอม" ข้อมูลขนาดเล็กที่สุดสําหรับแอปของคุณ จำเป็นต้องมีการแบ่งกลุ่มเนื่องจากปัจจุบันมีการจํากัดขนาดการส่ง (แต่เราจะแก้ไขปัญหานี้ในช่องทางข้อมูลเวอร์ชันในอนาคต) คําแนะนําปัจจุบันสําหรับขนาดกลุ่มสูงสุดคือ 64KiB
เมื่อโอนไฟล์ไปยังอีกฝั่งหนึ่งเสร็จแล้ว คุณจะดาวน์โหลดไฟล์ได้โดยใช้แท็กแองเคอร์ ดังนี้
function saveFile(blob) {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'File Name';
link.click();
};
แอปการแชร์ไฟล์เหล่านี้ใน PubShare และ GitHub ใช้เทคนิคนี้ โดยทั้ง 2 แพลตฟอร์มนี้เป็นโอเพนซอร์สและเป็นรากฐานที่ดีสําหรับแอปการแชร์ไฟล์ที่อิงตาม RTCDataChannel
คุณทำอะไรได้บ้าง
RTCDataChannel
เปิดโอกาสให้สร้างแอปใหม่ๆ สำหรับการแชร์ไฟล์ เกมแบบหลายผู้เล่น และการส่งเนื้อหา
- การแชร์ไฟล์แบบเพียร์ทูเพียร์ตามที่อธิบายไว้ก่อนหน้านี้
- การเล่นเกมแบบผู้เล่นหลายคนที่จับคู่กับเทคโนโลยีอื่นๆ เช่น WebGL ดังที่เห็นใน BananaBread ของ Mozilla
- PeerCDN กำลังคิดค้นวิธีใหม่ในการแสดงเนื้อหา ซึ่งเป็นเฟรมเวิร์กที่ใช้การสื่อสารข้อมูลแบบ Peer-to-Peer เพื่อนำส่งชิ้นงานบนเว็บ
เปลี่ยนวิธีสร้างแอป
คุณให้บริการแอปที่น่าสนใจยิ่งขึ้นได้โดยใช้การเชื่อมต่อประสิทธิภาพสูงที่มีเวลาในการตอบสนองต่ำผ่าน RTCDataChannel
เฟรมเวิร์ก เช่น PeerJS และ PubNub WebRTC SDK ช่วยให้ใช้งาน RTCDataChannel
ได้ง่ายขึ้น และตอนนี้ API ได้รับการรองรับอย่างกว้างขวางในแพลตฟอร์มต่างๆ
การถือกำเนิดของ RTCDataChannel
อาจเปลี่ยนแปลงวิธีคิดเกี่ยวกับการโอนข้อมูลในเบราว์เซอร์