שליחת נתונים בין שני דפדפנים לצורך תקשורת, משחקים או העברת קבצים יכולה להיות תהליך מורכב למדי. כדי לעשות זאת, צריך להגדיר שרת להעברת נתונים ולשלם עליו, ואולי גם להתאים את התהליך למספר מרכזי נתונים. בתרחיש הזה, ייתכן זמן אחזור ארוך וקשה לשמור על פרטיות הנתונים.
אפשר לצמצם את הבעיות האלה באמצעות שימוש ב-API RTCDataChannel
של WebRTC כדי להעביר נתונים ישירות מצד אחד לשני. במאמר הזה נסביר את העקרונות הבסיסיים של הגדרת ערוצי נתונים ושימוש בהם, וגם את תרחישים לדוגמה הנפוצים באינטרנט כיום.
למה עוד ערוץ נתונים?
יש לנו WebSocket, AJAX ו-Server Sent Events. למה אנחנו צריכים ערוץ תקשורת נוסף? WebSocket הוא דו-כיווני, אבל כל הטכנולוגיות האלה מיועדות לתקשורת אל שרת או משרת.
RTCDataChannel
משתמשת בגישה שונה:
- הוא פועל עם ממשק ה-API של
RTCPeerConnection
, שמאפשר קישוריות מקצה לקצה. כך אפשר לצמצם את זמן האחזור – אין שרת ביניים ופחות 'קפיצות'. RTCDataChannel
משתמש ב-Stream Control Transmission Protocol (SCTP), שמאפשר הגדרה של סמנטיקה של העברה מחוץ לסדר והגדרה של שליחה חוזרת.
RTCDataChannel
זמין עכשיו עם תמיכה ב-SCTP במחשב וב-Android בדפדפנים Google Chrome, Opera ו-Firefox.
אזהרה: איתות, STUN ו-TURN
WebRTC מאפשר תקשורת בין שווים, אבל עדיין נדרשים שרתים לאיתור כדי להחליף מטא-נתונים של מדיה ורשתות כדי להתחיל חיבור בין שווים.
WebRTC מתמודד עם NAT וחומות אש באמצעות:
- מסגרת ICE כדי לקבוע את נתיב הרשת הטוב ביותר האפשרי בין שווים.
- שרתי STUN – כדי לקבוע כתובת IP ויציאה נגישים לציבור של כל אפליקציה להשוואה.
- שרתי TURN אם החיבור הישיר נכשל ונדרש העברת נתונים.
למידע נוסף על האופן שבו WebRTC פועל עם שרתים לצורכי איתות ורשתות, אפשר לעיין במאמר WebRTC בעולם האמיתי: STUN, TURN ואיתות.
היכולות
ה-API של RTCDataChannel
תומך בקבוצה גמישה של סוגי נתונים. ה-API תוכנן לחקות את WebSocket בדיוק, ו-RTCDataChannel
תומך במחרוזות וגם בחלק מהסוגים הבינאריים ב-JavaScript, כמו Blob, ArrayBuffer ו-ArrayBufferView. הסוגים האלה יכולים להיות מועילים כשעובדים עם העברת קבצים ומשחקים מרובי משתתפים.
RTCDataChannel
יכול לפעול במצב לא מהימן ולא מסודר (בדומה לפרוטוקול User Datagram או ל-UDP), במצב מהימן ומאורגן (בדומה ל-Transmission Control Protocol או TCP), ובמצבים מהימנים חלקיים:
- המצב 'מהימן ומסודר' מבטיח את העברת ההודעות ואת הסדר שבו הן נמסרות. הפעולה הזו דורשת תקורה נוספת, ולכן יכול להיות שהמצב הזה יהיה איטי יותר.
- במצב לא מהימן ולא מסודר אין ערובה שכל ההודעות יגיעו לצד השני, או באיזה סדר הן יגיעו. כך אפשר להסיר את התקורה, וכך המצב הזה פועל מהר יותר.
- המצב 'אמין חלקית' מבטיח את העברת ההודעה בתנאים ספציפיים, כמו זמן קצוב לשליחת ההודעה מחדש או מספר מקסימלי של שליחות חוזרות. אפשר גם להגדיר את סדר ההודעות.
הביצועים בשני המצבים הראשונים זהים כמעט, אם אין אובדן מנות. עם זאת, במצב מהימן ומסודר, חבילה שאבדה גורמת לחסימה של חבילות אחרות שמגיעות אחריה, וייתכן שהחבילה שאבדה תהיה לא רלוונטית עד שהיא תישלח מחדש ותגיע. כמובן שאפשר להשתמש בכמה ערוצי נתונים בתוך אותה אפליקציה, לכל אחד מהם סמנטיקה מהימנה או לא מהימנה.
הטבלה הבאה מבוססת על רשת דפדפן עם ביצועים גבוהים מאת Ilya Graigorik:
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 הבאים: פרוטוקול העברת בקרה בסטרימינג ותוסף אמינות חלקית לפרוטוקול שידור Control Transmission.
ordered
: אם ערוץ הנתונים מבטיח שהסדר יהיה בסדר או לאmaxPacketLifeTime
: משך הזמן המקסימלי לנסות לשלוח מחדש הודעה שנכשלהmaxRetransmits
: מספר הפעמים המקסימלי לניסיון לשדר מחדש הודעה שנכשלהprotocol
: מאפשר שימוש בפרוטוקול משנה שמספק מטא מידע כלפי האפליקציהnegotiated
: אם ההגדרה היא true, המערכת לא תגדיר באופן אוטומטי ערוץ נתונים בצד השני, ותצטרכו ליצור ערוץ נתונים עם אותו מזהה בצד השני בעצמכם.id
: מאפשר לכם לספק מזהה משלכם לערוץ, שאפשר להשתמש בו רק בשילוב עםnegotiated
שמוגדר כ-true
)
רוב האנשים צריכים להשתמש רק בשלוש האפשרויות הראשונות: ordered
, maxPacketLifeTime
ו-maxRetransmits
. ב-SCTP (שכל הדפדפנים שתומכים ב-WebRTC משתמשים בו עכשיו) הערכים 'מהימן' ו'מסודר' מוגדרים כ-true כברירת מחדל. אם אתם רוצים שליטה מלאה משכבת האפליקציות, כדאי להשתמש בנתונים לא מהימנים או לא מסודרים, אבל ברוב המקרים כדאי להשתמש באמינות חלקית.
שימו לב שכמו ב-WebSocket, RTCDataChannel
יוצר אירועים כשמתבצע חיבור, כשהחיבור נסגר או כשיש שגיאות, וכשהוא מקבל הודעה מהצינור השני.
זה בטוח?
הצפנה היא חובה בכל הרכיבים של WebRTC. ב-RTCDataChannel
, כל הנתונים מאובטחים באמצעות Transport Layer Security ל-Datagram (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) ולשמור אותם בדיסק של המשתמש רק כשהקובץ נמצא במלואו. - גודל מקטע: אלה 'האטומים' הקטנים ביותר של הנתונים באפליקציה. חלוקה למקטעים נדרשת כי יש כרגע מגבלת גודל לשליחה (הבעיה הזו תיפתר בגרסה עתידית של ערוצי הנתונים). ההמלצה הנוכחית לגבי גודל מקטע מקסימלי היא 64KiB.
אחרי שהקובץ יועבר במלואו לצד השני, תוכלו להוריד אותו באמצעות תג עוגן:
function saveFile(blob) {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'File Name';
link.click();
};
אפליקציות שיתוף הקבצים האלה ב-PubShare וב-GitHub משתמשות בשיטה הזו. שניהם בקוד פתוח ומספקים בסיס טוב לאפליקציית שיתוף קבצים שמבוססת על RTCDataChannel
.
אז מה אפשר לעשות?
RTCDataChannel
פותח דרכים חדשות לפתח אפליקציות לשיתוף קבצים, למשחקים מרובי משתתפים ולמסירת תוכן.
- שיתוף קבצים בין משתמשים (P2P) כפי שמתואר למעלה
- משחקים מרובי משתתפים בשילוב עם טכנולוגיות אחרות, כמו WebGL, כפי שמוצג ב-BananaBread של Mozilla
- העברת תוכן לפי המצאה מחדש של PeerCDN, מסגרת שמספקת נכסי אינטרנט באמצעות תקשורת נתונים מקצה לקצה (PeerCDN)
שינוי הדרך שבה אתם בונים אפליקציות
עכשיו אתם יכולים לספק אפליקציות שמעוררות יותר עניין באמצעות חיבורים עם ביצועים גבוהים וזמן אחזור קצר דרך RTCDataChannel
. מסגרות כמו PeerJS ו-PubNub WebRTC SDK מאפשרות להטמיע את RTCDataChannel
בקלות רבה יותר, ול-API יש עכשיו תמיכה רחבה בכל הפלטפורמות.
ההשקה של RTCDataChannel
יכולה לשנות את האופן שבו אתם חושבים על העברת נתונים בדפדפן.