發(fā)布于:2020-12-19 19:03:18
0
224
0
您曾經(jīng)在iPhone或Mac上使用過(guò)AirDrop嗎?
好的,如果還沒(méi)有,您是否可以想象一下,只需按一下按鈕就可以在手機(jī)或筆記本電腦之間無(wú)縫共享文件?
由Robin Linus創(chuàng)建的SnapDrop.net允許您使用瀏覽器在任何設(shè)備之間直接共享文件。不管是在iPhone和Android還是裝有PC的平板電腦之間。
無(wú)需上傳到云或從云下載。?
那么到底是怎么工作的呢?
在逐行分析之后,我找出了它的出色架構(gòu)。在這篇文章中,我將向您展示其工作原理。
了解這項(xiàng)技術(shù)可以使您與尚未探索其功能的其他工程師區(qū)分開(kāi)。
WebRTC(Web實(shí)時(shí)通信)是一項(xiàng)了不起的技術(shù),僅在幾年前才問(wèn)世。其數(shù)據(jù)通道使SnapDrop可以將字節(jié)(甚至是音頻和視頻?。┲苯訌囊粋€(gè)對(duì)等方發(fā)送到另一對(duì)等方。
(將對(duì)等設(shè)備當(dāng)作手機(jī)或筆記本電腦之類(lèi)的設(shè)備)
但是,WebRTC無(wú)法在沒(méi)有幫助的情況下連接兩個(gè)用戶。它需要一個(gè)信令服務(wù)器,換句話說(shuō),它需要一些東西來(lái)發(fā)現(xiàn)其他對(duì)等節(jié)點(diǎn)并顯示如何連接。
ICE(交互式連接建立)是計(jì)算機(jī)在沒(méi)有公共IP地址的情況下如何從Internet到其自身繪制地圖的方法。這是由于路由器和計(jì)算機(jī)之間發(fā)生了NAT(網(wǎng)絡(luò)地址轉(zhuǎn)換)。
制作完地圖后,您將為這兩種設(shè)備找到某種相互共享其地圖的方法。SnapDrop通過(guò)NodeJS服務(wù)器執(zhí)行此操作,該服務(wù)器使用WebSockets(另一個(gè)很棒的協(xié)議)在每個(gè)對(duì)等方之間進(jìn)行通信。
現(xiàn)在您可能正在考慮,這安全嗎?
默認(rèn)情況下,WebRTC在傳輸中會(huì)加密其數(shù)據(jù)。太酷了,除了您之外,其他所有人也可能不想與隨機(jī)的人共享文件。
SnapDrop僅在具有相同IP地址的兩臺(tái)計(jì)算機(jī)之間共享ICE,這意味著它們位于同一網(wǎng)絡(luò)/ WiFi中。
它通過(guò)為每個(gè)IP地址創(chuàng)建房間來(lái)實(shí)現(xiàn)此目的,并通過(guò)生成唯一ID來(lái)區(qū)分設(shè)備。
/* Code to handle joining peers from the server */_joinRoom(peer) {
// if room doesn't exist, create it
if (!this._rooms[peer.ip]) {
this._rooms[peer.ip] = {};
}
// add this peer to room
this._rooms[peer.ip][peer.id] = peer;}
您可能不希望在公共wifi上使用此應(yīng)用,因?yàn)槟菢尤魏稳硕伎梢詫⑽募l(fā)送給您。但是在這種大流行中,無(wú)論如何誰(shuí)要出去?♀?
上面的代碼片段通過(guò)將對(duì)等體存儲(chǔ)在服務(wù)器類(lèi)的一個(gè)對(duì)象中而做出了一個(gè)有趣的選擇。通常,您希望使用數(shù)據(jù)庫(kù),但這可能是為了簡(jiǎn)化操作,并且該應(yīng)用程序可能沒(méi)有很多流量。
樣式幾乎與AirDrop一樣。每個(gè)設(shè)備都有一個(gè)有趣的名稱(chēng)和一個(gè)圖標(biāo),以幫助區(qū)分每個(gè)對(duì)等設(shè)備。不僅如此,它還有一個(gè)漸進(jìn)式Web應(yīng)用程序,它提供了一些不錯(cuò)的功能,例如:
感覺(jué)像本地應(yīng)用程序
通知事項(xiàng)
實(shí)時(shí)更新
到目前為止,大多數(shù)設(shè)備/瀏覽器都支持WebRTC,但如果不支持WebRTC,則SnapDrop具有后備功能!在這種情況下,它使用已經(jīng)建立的WebSocket連接來(lái)發(fā)送文件數(shù)據(jù)。
但是,這效率較低且安全性較低,因?yàn)閿?shù)據(jù)需要先到達(dá)服務(wù)器,然后再到達(dá)其最終目的地。
if (window.isRtcSupported && peer.rtcSupported) {
this.peers[peer.id] = new RTCPeer(this._server, peer.id);} else {
this.peers[peer.id] = new WSPeer(this._server, peer.id);}
代碼庫(kù)完全是事件驅(qū)動(dòng)的。當(dāng)您要使服務(wù)彼此分離并允許在發(fā)生操作時(shí)進(jìn)行處理時(shí),可以使用此樣式。
這是對(duì)WebRTC和WebSocket的補(bǔ)充,因?yàn)樗鼈円彩鞘录?qū)動(dòng)的。當(dāng)消息進(jìn)入,或者有新的同伴加入,或者想要發(fā)送文件時(shí),這就是事件。
一開(kāi)始很難遵循,因?yàn)樗皇蔷€性過(guò)程。這是注冊(cè)和觸發(fā)事件的類(lèi)。
class Events {
static fire(type, detail) {
window.dispatchEvent(new CustomEvent(type, { detail: detail }));
}
static on(type, callback) {
return window.addEventListener(type, callback, false);
}}
這樣您就可以編寫(xiě)這樣的事件驅(qū)動(dòng)代碼
Events.on('signal', e => this._onMessage(e.detail));Events.on('peers', e => this._onPeers(e.detail));Events.on('files-selected', e => this._onFilesSelected(e.detail));Events.on('send-text', e => this._onSendText(e.detail));Events.on('peer-left', e => this._onPeerLeft(e.detail));
希望您今天學(xué)到了一些東西!如果您想親自探索代碼,請(qǐng)?jiān)L問(wèn)github存儲(chǔ)庫(kù)。https://github.com/RobinLinus/snapdrop
創(chuàng)建者還很友好地創(chuàng)建了docker compose文件,因此您可以自己運(yùn)行和托管該文件。我想知道有多少人在運(yùn)行自己的SnapDrop實(shí)例?
您如何看待這類(lèi)博客文章?我覺(jué)得我不得不寫(xiě)這篇文章,因?yàn)檫@個(gè)項(xiàng)目教會(huì)了我一些寶貴的經(jīng)驗(yàn)。在下面發(fā)表評(píng)論,我會(huì)盡快回復(fù)大家!
下一個(gè)再見(jiàn)?。
作者介紹
熱門(mén)博客推薦