Home Chat 局域网家庭聊天
找一台电脑当服务器一直开着,家里人手机连同一个 WiFi,浏览器打开就能聊。 不用注册,不用装 App,聊天记录加密存在自己电脑上。
本站不直接放文件,点上面的按钮会跳到网盘去拿(源码在 GitHub 上)。 下面这份说明是按「从零开始」写的 —— 电脑怎么装、手机怎么连、连不上怎么查,都在里面。 全都放在本地,不需要买服务器,也不用域名。
家里的聊天工具。
找一台电脑当服务器,一直开着。家里人手机连同一个 WiFi,浏览器打开就能聊。不用注册,不用装 App,聊天记录加密存在自己电脑上,不上云。
现在只有 macOS 版。Windows 版还在做,功能一样,区别只在怎么装,装法会另外写一份。
初始密码是
123456,跑起来之后记得改成自己的,怎么改往下看。
要准备什么
一台 Mac,一直开着当服务器 —— macOS 11 以上(Big Sur 之后的都行)。
Node.js 18 以上。没有的话去 nodejs.org 下 LTS 版,双击,一路下一步。
家里人手机和这台 Mac 连同一个 WiFi。
就这几样。不用买服务器,不用域名,不用备案,也不用公网 IP。
手机端不用装 App,浏览器打开就行;想当 App 用,Safari 里点分享、选「添加到主屏幕」。
怎么装
第一步 · 装 Node.js
终端里敲:
node -v能出来版本号就有了。没有就去 nodejs.org 装一个,装完把终端窗口关了重开,再敲一次确认。
第二步 · 装依赖
整个项目只用了一个外部库(ws,200 多 KB)。
拿到的是我打包好的 zip,里面已经带了,这步跳过。从 GitHub 上 clone 下来的话仓库里没有,装一下:
cd servernpm install项目里配好了国内镜像,不用梯子。
第三步 · 启动
双击 启动HomeChat.command。
第一次双击,系统可能说「无法打开,来自身份不明的开发者」—— 右键点它,选「打开」,再点一次「打开」。以后就不问了。
窗口里会刷一堆东西,最后停在两行:
就绪 192.168.1.23:8787[udp] 设备发现已监听 8787/udp前面那个 192.168.1.23 就是要记的地址。每台机器不一样,以你自己窗口里打印的为准。 这个窗口别关,关了服务就停了,最小化没问题。
第四步 · 手机连上来
手机浏览器打开 http://192.168.1.23:8787(换成你自己那个),然后填:
| 填什么 | 填成什么 |
|---|---|
| 电脑地址 | 上面那个 |
| 你的名字 | 随便起,比如「爸爸」 |
| 密码 | 123456 |
点连接。第一次不会直接进去 —— 手机还没入册,得先在电脑上放行一次。
第五步 · 在电脑上放行
双击 打开服务监控.command。
页面上会跳出一条待批准,写着「某某手机想加入」,点【同意】,手机那边立刻就进去了。
也可以看启动服务那个黑窗口,那里也会提示,按 Y 再回车。
放行一次就够了,但每台手机第一次都得放行。
六个快捷方式
| 双击这个 | 干什么 |
|---|---|
启动HomeChat.command | 开始服务,平时就双击这个 |
停止HomeChat.command | 停掉服务 |
打开服务监控.command | 看监控面板,新手机也在这里放行 |
打开电脑版聊天.command | 在 Mac 上直接聊 |
改密码.command | 改聊天密码和后台密码 |
清空数据.command | 账号和聊天记录全清掉 |
监控面板也能自己开浏览器输:http://127.0.0.1:8787/admin。密码跟聊天密码一样,除非你单独设了后台密码。
面板上只有统计数字:谁在线、今天发了多少条、内存占了多少、阅后即焚排掉多少条。聊天内容一条都看不到。
怎么用
聊天
电脑上回车是发送,Shift + 回车 是换行。
手机上回车是换行,点右边那个按钮发送 —— 手机键盘没有 Shift,只能这样。
发图片和文件
点输入框左边的 +。
图片先在手机上压到长边 1280 像素再发,省流量也省电脑内存。原图最大 40MB,压完大概 3MB。普通文件最大 32MB。
语音
点输入框左边那个话筒,按住说话。最长 60 秒,到点自动发。
松手不会直接发出去,会先出来一条:
3″ [试听] [重录] [取消] [发送]先听一遍,不满意点重录,满意了点发送。
阅后即焚
一直开着,关不掉。对方读完 30 秒,服务端把那条从硬盘上抹掉。
界面上没有任何提示。 没有小火苗,没有倒计时,没有「已销毁」。这是故意的。
撤回
自己发的消息,2 分钟之内能撤回。长按那条,点撤回。
撤回之后两边都变成「你撤回了一条消息」,服务端硬盘上那条也一起抹掉。
已读
对方看了,你这条会变成「已读」。纯文字,没有对勾。
搜索
会话列表顶上搜的是人和群。
想搜聊天记录,进那个聊天,点右上角放大镜,搜的是这个聊天里的内容。
改密码
双击 改密码.command。
两个密码:聊天密码是家里人手机连上来输的那个,后台密码是开监控面板输的那个。可以设成一样的,省事;也可以分开,更保险 —— 知道聊天密码的人就进不了后台。
改密码的时候会把所有聊天记录重新加密一遍,一条都不会丢。
为什么要重新加密:密码不是存在某个地方等着比对的,它本身就是加密用的钥匙。换钥匙就得把旧数据全解开,再用新钥匙重新封上。
改完之后:
- 双击
启动HomeChat.command重启 - 每台手机用新密码重新登一次
- 手机上那份旧存档读不出来了(也是旧钥匙加的密),不要紧,重新登录会从电脑上把记录拉回来
- 开监控面板用后台密码
改之前会自动备份一份到 data.备份-时间戳,反悔了把那个目录改回 data 就行。
密码存在 data/config.local.json 里,不在代码里,所以项目传到 GitHub 上也不会带出你的密码。那个文件权限是 600,只有你自己读得到。
清空数据
双击 清空数据.command。
会删掉:聊天记录、成员账号、群聊、备注名、头像、已读位置、撤回记录,还有加密钥匙本身。 不会动:代码,密码设置(密码还是你现在那个)。
手机上的本地存档不归它管,那个在手机里,要清得在手机上清。
跑之前要输 YES 确认,也会先自动备份一份。跑的时候服务端必须是停的,先双击 停止HomeChat.command。
连不上怎么办
先查这三条,九成的问题都在这:
- 手机和电脑是不是同一个 WiFi —— 手机用流量,或者一个连 5G 频段一个连 2.4G,有时候也算两个网
- 电脑上那个黑窗口还开着吗 —— 关了服务就停了
- 地址有没有抄错 —— 以电脑窗口里打印的为准,别猜
还是不行,多半是路由器的 AP 隔离。
这是连不上的头号原因。不少路由器默认开着「AP 隔离」或者「客户端隔离」,同一个 WiFi 下的设备互相看不见,自然连不上。去路由器后台看看(浏览器打开 192.168.1.1 或 192.168.0.1),在「无线设置」一类的页面里,把 AP 隔离、客户端隔离、无线隔离这几个开关关掉。各家叫法不同,意思都一样。
电脑休眠了怎么办
笔记本合盖就休眠,服务跟着停。想让它一直跑:系统设置 → 锁定屏幕 → 关掉「显示器关闭时自动进入睡眠」,插电那边把「防止电脑自动进入睡眠」打开。台式机(iMac、Mac mini、Mac Pro)不用管这条。
手机那边什么都不用做。醒来自己重连,中间错过的消息一条不差地补回来。
手机上的一些事
收不到消息提醒 —— 安卓为了省电会杀后台,各家杀法还不一样。进「我的」→「后台收消息」,那里认得出你是什么牌子的手机,会写出对应的设置步骤,点一下还能直接跳到系统设置页。小米、vivo、华为、OPPO、三星、谷歌都做了。
禁止截屏 —— 安卓上能拦,系统级的,截屏会提示「无法截图」。iPhone 上拦不了,苹果没给这个接口,浏览器里也拦不了。「我的」→「防护状态」会如实告诉你这台到底拦住没有:显示「系统没拦住截屏」就是真没拦住,换个地方也一样。
加到桌面 —— Safari 打开聊天页,点分享,选「添加到主屏幕」,用起来跟 App 差不多。
项目目录里都是什么
app/ 网页源码,手机和电脑共用这一份 index.html 页面结构 css/ 样式 js/ 逻辑 hc1.js 加密 store.js 本地数据 net.js 跟服务端通信 media.js 图片、语音、文件 ui.js 界面渲染 app.js 主流程 logo.png 登录页图标,想换直接替换这个文件
server/ 服务端 src/ index.js 启动入口 hub.js 消息转发中心 store.js 数据落盘 http.js HTTP 接口 crypto.js 加密实现 net.js 网络看门狗,断网自动停服 filecache.js 文件中转,只在内存里 discovery.js UDP 设备发现 config.js 配置 setpass.js 改密码 cleardata.js 清空数据 showpass.js 把当前密码打出来,给快捷方式用 各种 test.js 自检,跑法看下面
admin/ 监控面板
data/ 你的数据,自动生成,不会传到 GitHub 上
带 .command 的 双击就能跑的脚本跑测试
cd servernpm test想单独跑某一种:
node src/selftest.js 加密层的标准测试向量node src/domtest.js 页面元素和 JS 引用对不对得上node src/apitest.js 模块之间调用的方法存不存在node src/crosstest.js 手机端和服务端的加密对不对得上node src/webtest.js 页面和各种地址能不能正常加载node src/boottest.js 把界面启动一遍看会不会崩node src/voicetest.js 录音权限和语音消息node src/e2etest.js 两台手机连上来跑完整的收发node src/audit.js 安全自查,起一个真服务端试各种越权这些测试都跑在临时目录里,不会碰你的 data/。
技术上的几件事
加密 —— 内容用 HMAC-SHA256 做的流密码,先加密再签名。钥匙从密码来,PBKDF2-HMAC-SHA256 跑 30 万轮。
局域网里跑的是明文 http。内容本身是密的,但抓包能看出「谁在跟谁说话、什么时候、大概多大的量」。为什么不上 https:家里没域名没证书,自签证书浏览器一片红,还得教家里人点「继续访问」,不划算。
协议 —— 一个 8787 端口干四件事:HTTP 页面、WebSocket 聊天、文件上传、UDP 设备发现。防火墙只开一个口,家里人只记一个地址。
文件中转不写盘 —— 发的图片、语音、文件只在服务端内存里待 5 分钟。对方取走或者超时就丢,一个字节都不落硬盘。所以对方当时不在线就收不到了,消息还在,点开时会说「文件已不在」。单个文件上限 32MB,内存总共 64MB,超了按最老的先丢。
消息不会丢 —— 每条消息有个服务端生成的连续编号。客户端记着「我收到第几号了」,断线、锁屏、切出去再回来,带着这个号去要缺的那一段。不看时间戳 —— 时间戳是发送方手机给的,手机时钟不准就乱套了。
已知限制
iPhone 后台收不到消息 —— 苹果只让它的推送服务唤醒 App,你家这台 Mac 不在那套体系里。实际用起来是:打开就实时收,锁屏期间的消息在打开那一瞬间全部补上,一条不丢。
安卓 App 被杀之后收不到通知 —— 同上,本地通知得进程活着才能弹。真正的离线推送要接厂商通道,那要注册账号、消息过第三方服务器,跟「不上云」冲突,所以没做。
浏览器里拦不了截屏 —— 网页没有这个接口,只有原生 App 能拦。
电脑休眠等于服务停 —— 醒了自动恢复,手机也会自己重连。
别人拿另一台手机拍你的屏幕 —— 这个任何软件都防不住。
许可
MIT。随便用,随便改。