一个开发人员如何仅使用JavaScript重新创建AirDrop

发布于:2020-12-19 19:03:18

0

181

0

开发人员 JavaScript AirDrop

您曾经在iPhone或Mac上使用过AirDrop吗?

好的,如果还没有,您是否可以想象一下,只需按一下按钮就可以在手机或笔记本电脑之间无缝共享文件?

由Robin Linus创建的SnapDrop.net允许您使用浏览器在任何设备之间直接共享文件。不管是在iPhone和Android还是装有PC的平板电脑之间。

无需上传到云或从云下载。?

那么到底怎么工作的呢?

在逐行分析之后,我找出了它的出色架构。在这篇文章中,我将向您展示其工作原理。

使用这项新技术

了解这项技术可以使您与尚未探索其功能的其他工程师区分开。

WebRTC(Web实时通信)是一项了不起的技术,仅在几年前才问世。其数据通道使SnapDrop可以将字节(甚至是音频和视频!)直接从一个对等方发送到另一对等方。

(将对等设备当作手机或笔记本电脑之类的设备)

但是,WebRTC无法在没有帮助的情况下连接两个用户。它需要一个信令服务器,换句话说,它需要一些东西来发现其他对等节点并显示如何连接。

没有此功能就无法使用WebRTC

体系结构图。 NodeJS Server通过Web套接字连接到电话和计算机。 手机和计算机与WebRTC连接

ICE(交互式连接建立)是计算机在没有公共IP地址的情况下如何从Internet到其自身绘制地图的方法。这是由于路由器和计算机之间发生了NAT(网络地址转换)。

制作完地图后,您将为这两种设备找到某种相互共享其地图的方法。SnapDrop通过NodeJS服务器执行此操作,该服务器使用WebSockets(另一个很棒的协议)在每个对等方之间进行通信。

现在您可能正在考虑,这安全吗?

好的,但是您如何确保该东西呢?

默认情况下,WebRTC在传输中会加密其数据。太酷了,除了您之外,其他所有人也可能不想与随机的人共享文件。

SnapDrop仅在具有相同IP地址的两台计算机之间共享ICE,这意味着它们位于同一网络/ WiFi中。

它通过为每个IP地址创建房间来实现此目的,并通过生成唯一ID来区分设备。

/* 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上使用此应用,因为那样任何人都可以将文件发送给您。但是在这种大流行中,无论如何谁要出去?♀️

上面的代码片段通过将对等体存储在服务器类的一个对象中而做出了一个有趣的选择。通常,您希望使用数据库,但这可能是为了简化操作,并且该应用程序可能没有很多流量。

熟悉的用户界面和用户体验

SnapDrop网站,带有用于两台计算机和一部电话的图标

样式几乎与AirDrop一样。每个设备都有一个有趣的名称和一个图标,以帮助区分每个对等设备。不仅如此,它还有一个渐进式Web应用程序,它提供了一些不错的功能,例如:

  • 感觉像本地应用程序

  • 通知事项

  • 实时更新

如果设备不支持WebRTC怎么办?

到目前为止,大多数设备/浏览器都支持WebRTC,但如果不支持WebRTC,则SnapDrop具有后备功能!在这种情况下,它使用已经建立的WebSocket连接来发送文件数据。

但是,这效率较低且安全性较低,因为数据需要先到达服务器,然后再到达其最终目的地。

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);}

事件驱动的代码样式

代码库完全是事件驱动的。当您要使服务彼此分离并允许在发生操作时进行处理时,可以使用此样式。

这是对WebRTC和WebSocket的补充,因为它们也是事件驱动的。当消息进入,或者有新的同伴加入,或者想要发送文件时,这就是事件。

一开始很难遵循,因为它不是线性过程。这是注册和触发事件的类。

class Events {
    static fire(type, detail) {
        window.dispatchEvent(new CustomEvent(type, { detail: detail }));
    }
    static on(type, callback) {
        return window.addEventListener(type, callback, false);
    }}

这样您就可以编写这样的事件驱动代码

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));

自己检查代码

希望您今天学到了一些东西!如果您想亲自探索代码,请访问github存储库。https://github.com/RobinLinus/snapdrop

创建者还很友好地创建了docker compose文件,因此您可以自己运行和托管该文件。我想知道有多少人在运行自己的SnapDrop实例?

谢谢阅读!

您如何看待这类博客文章?我觉得我不得不写这篇文章,因为这个项目教会了我一些宝贵的经验。在下面发表评论,我会尽快回复大家!

下一个再见✌。