这是我第一个写完还敢给别人看的东西,所以放在最前面写。
一开始只是不想让家里人再装一个 App
事情特别小。我妈要在手机上给我传个文件,得先加好友、再发、再下载, 中间还要过一遍别人的服务器。我爸就更烦了,他嫌麻烦,干脆用微信发给自己。
家里其实有一台 Mac 一直开着(我写代码就用它)。我就想, 那台电脑和手机在同一个 WiFi 里,直接连它不就行了,为什么非要绕一圈。
所以这个东西的定位从一开始就很窄:只在同一个 WiFi 下用。 不用买服务器,不用域名,不用备案,也不用公网 IP。 代价是出了家门就用不了 —— 我认了这个代价。
从”能发一句话”开始
第一版特别小,就三个文件:一个 Node 起 HTTP 服务的, 一个管 WebSocket 转发的,一个网页界面。能做的事只有一件: 两台设备同时打开页面,一边打字,另一边能看到。
跑起来的时候窗口里打印这么两行,我盯着看了好一会儿:
就绪 192.168.1.23:8787[udp] 设备发现已监听 8787/udp第二行是后来才加的。因为第一版有个特别蠢的问题:
家里人得手动输 192.168.1.23:8787 这一串东西,
我爸输错了三次,然后就放弃去用微信了。
后来我加了个 UDP 广播:服务器每隔几秒往局域网里喊一声”我在这儿”, 网页那边收到就自动填进地址栏。现在他们只要点一下”添加到主屏幕”, 以后从桌面上点开就直接进去了。
后来越加越多
能用之后就不受控制了。现在里面有这些东西:
-
群聊。家里人建一个”家里”的群,不用一个个发。
-
发图片。先在手机上压到长边 1280 像素再发,原图最大 40MB,压完大概 3MB。
-
发文件,单个最大 32MB。
-
按住说话的语音。松手不会直接发出去,会先出来一条让你试听、重录, 满意了才发。这个是我妈的反馈,她说她老按错。
-
撤回,自己发的消息两分钟之内能撤,撤了之后服务端硬盘上那条也一起抹掉。
-
阅后即焚。一直开着、关不掉,对方读完 30 秒,服务端把那条从硬盘上抹掉。 界面上没有任何提示 —— 没有小火苗,没有倒计时,这是故意的。
还有一个后台监控面板,能看谁在线、今天发了多少条、内存占了多少、阅后即焚排掉多少条。 聊天内容一条都看不到,只看数字。
现在长什么样
目录大概是这样分的:
app/ 手机端网页 index.html css/ 界面样式 js/ crypto 加密 / store 本地数据 / net 通信 media 图片语音文件 / ui 渲染 / app 主流程server/ 服务端 src/ index 启动 / hub 消息转发 / store 落盘 http 接口 / crypto 加密 / filecache 内存中转 discovery UDP 设备发现 / net 断网看门狗admin/ 监控面板data/ 我自己的数据,不传到 GitHub 上服务端只依赖一个外部库 ws,两百多 KB,纯 JS,不用原生编译。
剩下全是自己写的。不是我厉害,是因为我想让它在我爸那台旧电脑上也能跑起来。
做完之后才明白的几件事
第一,难的不是”让两台电脑说上话”,难的是”说不上话的时候怎么办”。 手机锁屏、切出去、WiFi 断一下,这些都是天天发生的, 我一开始完全没管,结果用两天就发现丢消息。
第二,我一开始觉得”自己写的东西不用测试”。 后来改加密那部分,改完自己都忘了原来是什么行为,只好写了个标准测试向量跑一遍。 现在服务端有 7 个自检脚本加 1 个安全自查,改完代码先跑一遍再说。
第三,家里人用起来是不看说明书的。我写了一大段”点这里再点那里”, 我妈一句没看,直接就在群里发了个表情。所以后来我把能自动的全自动了, 地址自动填、第一次连上在电脑上点一下”同意”就行,之后就再也不问了。
代码在 GitHub 上,MIT,随便看随便改。现在只有 macOS 版,Windows 的还在做。