在IIS服务器上搭建自己的Snapdrop服务
2021/11/15 计算机 次 8 条
2021年11月20日更新SnapDrop汉化增强版2.0,加入了公网支持,不在同一局域网内的多个设备只要输入同一个接头暗号,就能彼此发现对方并点对点传输文件。
Snapdrop是一个不用安装任何软件,只用浏览器就能传输文件的神器。类似于苹果的AirDrop,是P2P的直传,但是比AirDrop更强大的是能跨平台在Windows、Mac、IOS、安卓之间互传文件。
同局域网内的两台设备只要在浏览器上同时打开网址:https://snapdrop.net 就可以互相传送文件,是不是很神奇!
打开一看,这个项目居然是开源的,项目地址:https://github.com/RobinLinus/snapdrop
于是我决定在自己的服务器上也部署一个snapdrop的镜像。这个项目是运行在node.js上的,然后使用nginx反向代理,github上发布的是docker版。说实话,我看到这个项目的时候连什么是node.js都不知道,就连docker我也只是仅仅听说过这个名字而已。没关系,反正最近疫情严重,复工遥遥无期,有的是时间,慢慢研究吧。经过几天的捣腾,终于在我的windows云主机的IIS服务器上跑起来了,顺便我还汉化了一下。下面我就简单说一下搭建的方法。
所需工具:
1.Node.js,官网下载msi安装包,双击安装就可以了,网上教程一大堆,我就不重复了。
下载地址:https://nodejs.org/zh-cn/download/
2.IIS的反向代理插件Application Request Routing:
下载地址:https://www.iis.net/downloads/microsoft/application-request-routing
原作者的版本是将后端server部分运行在node.js服务器里,启动一个http://localhost:3000的本地服务,然后用nginx的反向代理功能,将wss://snapdrop.net/server/webrtc的请求转发到http://localhost:3000上,发送给前端的静态资源直接用nginx处理。这样部署起来在IIS里有点复杂,于是我找到了一个把静态和动态全部交给node.js来处理的branch:https://github.com/Bellisario/node-snapdrop 这个动静合一的版本可能性能上没有动静分开的构架好,但是部署起来比较简单,所以我选择了这个版本。
运行起来其实很简单,作者简单的写了一下:
How to run
Download the repository in a folder, cd it, install all dependencies with
npm i
and use this command:node index.js
.
简单翻译一下:下载解压,打开cmd命令提示符,用cd指令进入到解压后的目录,先输入指令npm i
安装依赖模块,安装完成之后输入指令node index.js
启动服务,就这么简单。
服务运行在3000端口,而且没有https功能也不支持域名绑定,怎么办?这时我们就需要用IIS来反向代理一下。
IIS设置反向代理其实很简单,
1.随便建一个空白的网站,我这里域名和证书都是绑定的snapdrop.fairysoft.net
2.设置Application Request Routing,进入Server Proxy Settings...
勾上Enable proxy
选择Pass through
勾掉Include TCP port from client IP
3.在这个网站下设置URL重写,新建一条入站规则
模式匹配填入 ^(.*)
添加一个条件
输入为 {CACHE_URL}
模式为 ^(http|ws)s?://
重写URL填入 {C:1}://localhost:3000/{R:0}
一切OK!浏览器输入网址:https://snapdrop.fairysoft.net 测试一下,成功!
实测开热点也可以传,不用费流量。浏览器打开的这个网页只起到牵线搭桥的作用,设备之间文件传输是P2P直连。
据网友反馈,Chrome跟Safari兼容性最好,Edge跟Firefox也可以,华为自带的浏览器也支持,小米自带浏览器不行。
但是Firefox兼容性有点小问题,用Firefox的话,接收之前要把页面刷新一下,只有后刷新的设备才能接收文件,先刷新的只能发不能收。
【2021年11月19日更新】经过几天的排查,Firefox兼容性的Bug终于找到了。原来,Firefox在接收文件的时候,不管对方是什么浏览器,只要自己先载入页面,收到的数据包类型为Blob,如果自己比对方后载入,收到的数据包类型就变成了ArrayBuffer,其他浏览器就没这个问题,不管自己跟对方谁先打开,收到的数据包一律为ArrayBuffer类型。至于为什么这样,我也不懂,连Blob跟ArrayBuffer是什么我现在都没弄明白。知道了是这个问题就好办了,稍微修改了一行代码就OK了。
这个传输的原理据说是基于WebRTC,刚才百度了一下,WebRTC名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准。目的是通过浏览器提供简单的javascript就可以达到实时通讯(Real-Time Communications (RTC))能力。最终目的主要是让Web开发者能够基于浏览器(Chrome\FireFox\...)轻易快捷开发出丰富的实时多媒体应用,而无需下载安装任何插件,Web开发者也无需关注多媒体的数字信号处理过程,只需编写简单的Javascript程序即可实现。另外WebRTC还希望能够建立一个多互联网浏览器间健壮的实时通信的平台,形成开发者与浏览器厂商良好的生态环境。同时,Google也希望和致力于让WebRTC的技术成为HTML5标准之一。WebRTC提供了视频会议的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:windows,linux,mac,android。
实测了几款浏览器,没想到唯一不支持WebRTC的居然是我的小米手机原生浏览器。另外我还测试了一下各种浏览器传大文件的速度,结果很意外,安卓手机上用Chrome跟PC传文件速度非常慢,只有500KB/s的速度,最快的是Safari和Firefox,速度可以稳定在到10MB/s以上。