以前自己尝试或手写WetRTC来实现局域网文件传输功能,但是问题很多也不好用,博客如下:
本次使用成熟的第三方库 lw-share 来实现局域网文件传输功能。
环境准备
安装 Node v20(宝塔方式)
由于我的 Ubuntu 系统默认 Node 为 v14(npm 6.x),而 lw-share 要求 Node ≥ 18,需要单独使用 Node v20 来运行 lw-share,避免影响系统其他服务。
通过宝塔面板 → 软件商店 → Node.js 版本管理器 → 安装 Node v20.20.2,安装路径通常为:
1
| /www/server/nodejs/v20.20.2/
|
如果不确定宝塔安装的node20的路径,也可以先通过把node20版本设置为默认版本,然后再查看node路径。
验证node20是否安装成功
1
| /www/server/nodejs/v20.20.2/bin/node -v
|
关键点:lw-share 的 systemd 服务将写死使用此路径的 node 二进制,与系统默认 Node 版本完全解耦。
安装 lw-share
使用 Node v20 的 npm 全局安装
(这里建议将node20设置为默认版本,然后可以直接使用不带完整路径的node、npm和npx命令)
验证(临时启动测试)
浏览器访问 http://服务器IP:60889 确认能打开页面后 Ctrl+C 停止。
配置服务
创建服务文件 /etc/systemd/system/sendByLwShare.service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| [Unit] Description=LW-Share (local file share + chat) After=network-online.target Wants=network-online.target
[Service] Type=simple User=root Group=root
# 写死 Node v20 路径,不依赖 shell PATH ExecStart=/www/server/nodejs/v20.20.2/bin/node \ /www/server/nodejs/v20.20.2/lib/node_modules/lw-share/lw-share.mjs \ -P 60889
# 工作目录(上传文件存放在 ./share/ 子目录) WorkingDirectory=/root/lw-share-data
# 环境变量 Environment=PATH=/www/server/nodejs/v20.20.2/bin:/usr/bin:/bin Environment=LANG=C.UTF-8 Environment=LC_ALL=C.UTF-8
# 自动拉起 Restart=on-failure RestartSec=3
# 日志 StandardOutput=journal StandardError=journal SyslogIdentifier=lw-share
[Install] WantedBy=multi-user.target
|
准备工作目录
1
| mkdir -p /root/lw-share-data
|
启用服务
1 2 3 4
| systemctl daemon-reload systemctl enable sendByLwShare.service systemctl start sendByLwShare.service systemctl status sendByLwShare.service
|
查看日志
1
| journalctl -u sendByLwShare.service -f
|
防火墙与端口放行,通过宝塔面板 → 防火墙 → 端口放行 → 添加端口 60889
上传文件名乱码问题
问题现象:
- 上传中文名文件后,服务器 /root/lw-share-data/share/ 目录中文件名显示为乱码(如 åå京è…)
- 文件内容正常,仅文件名异常
- 下载到 Windows 后文件名仍为乱码
原因分析:
lw-share 在解析 multipart 上传时,将 UTF-8 编码的文件名按 Latin-1 单字节解码后直接落盘,导致 mojibake(编码错乱)。这是 lw-share 上游的已知行为,不修改源码的情况下需要从外部修复。
修复方案
使用外部脚本还原文件名。
创建手动批量修复脚本 /root/fix-lwshare-names.mjs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import fs from "fs"; import path from "path";
const dir = "/root/lw-share-data/share";
if (!fs.existsSync(dir)) { console.error("目录不存在:", dir); process.exit(1); }
const entries = fs.readdirSync(dir); let fixedCount = 0;
for (const name of entries) { let fixed; try { fixed = Buffer.from(name, "latin1").toString("utf8"); } catch { continue; } if (fixed === name) continue;
const oldPath = path.join(dir, name); let newPath = path.join(dir, fixed);
if (fs.existsSync(newPath)) { const ext = path.extname(fixed); const base = path.basename(fixed, ext); newPath = path.join(dir, `${base}.fixed-${Date.now()}${ext}`); }
try { fs.renameSync(oldPath, newPath); console.log(`✅ 修复: ${name} → ${fixed}`); fixedCount++; } catch (e) { console.error(`❌ 失败: ${name}`, e.message); } }
console.log(`\n完成:共修复 ${fixedCount} 个文件`);
|
手动执行修复
1
| node /root/fix-lwshare-names.mjs
|
自动监听修复
安装 inotify-tools
1
| apt install -y inotify-tools
|
创建监听脚本 /root/lwshare-watcher.sh
1 2 3 4 5 6 7 8 9
| #!/bin/bash DIR=/root/lw-share-data/share NODE=/www/server/nodejs/v20.20.2/bin/node SCRIPT=/root/fix-lwshare-names.mjs
inotifywait -m -e close_write -e moved_to "$DIR" --format '%f' | while read fname; do sleep 0.3 "$NODE" "$SCRIPT" >/dev/null 2>&1 done
|
为 /root/lwshare-watcher.sh 添加执行权限
1
| chmod +x /root/lwshare-watcher.sh
|
创建服务文件 /etc/systemd/system/lwShareFix.service
1 2 3 4 5 6 7 8 9 10 11 12 13
| [Unit] Description=LW-Share filename UTF-8 fixer (auto-rename) After=sendByLwShare.service
[Service] Type=simple ExecStart=/root/lwshare-watcher.sh Restart=on-failure RestartSec=5 Environment=LANG=C.UTF-8
[Install] WantedBy=multi-user.target
|
启用修复服务
1 2 3 4
| systemctl daemon-reload systemctl enable lwShareFix.service systemctl start lwShareFix.service systemctl status lwShareFix.service
|
此后每次上传文件,inotifywait 会在文件写入完成后自动触发修复脚本,将乱码文件名还原为中文。
常用管理命令速查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| systemctl start sendByLwShare.service systemctl stop sendByLwShare.service systemctl restart sendByLwShare.service systemctl status sendByLwShare.service
systemctl start lwShareFix.service systemctl stop lwShareFix.service systemctl restart lwShareFix.service systemctl status lwShareFix.service
journalctl -u sendByLwShare.service -n 50 --no-pager journalctl -u lwShareFix.service -f
/www/server/nodejs/v20.20.2/bin/node /root/fix-lwshare-names.mjs
ss -tlnp | grep 60889
|
注意事项与踩坑记录
| 问题 | 说明 |
|---|
| Node 版本冲突 | 系统默认 Node14 不能运行 lw-share,必须在 service 中写死 Node20 绝对路径 |
| PATH 未包含 npm bin | 直接执行 lw-share 命令找不到,需用 npx 或绝对路径调用 |
| 宝塔安全组 | 宝塔面板安全规则 + 系统 ufw 双层放行,缺一不可 |
| 切回 Node14 不影响 | service 写死 v20.20.2 路径,与宝塔默认版本切换无关 |
| 乱码不可逆条件 | 若文件名显示为 ??? 而非 åå…,说明字节已丢失,无法还原 |
| 端口选择 | 60889 为自定义端口,避免与常见服务(3000/8080)冲突 |
| 工作目录权限 | /root/lw-share-data 需确保运行用户(root)有读写权限 |
架构总结
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ┌─────────────────────────────────────────────────────┐ │ Ubuntu 主机(局域网) │ │ │ │ sendByLwShare.service │ │ ├── Node v20.20.2 (绝对路径) │ │ ├── lw-share.mjs -P 60889 │ │ └── 工作目录: /root/lw-share-data/share/ │ │ ├── 上传文件(初始乱码) │ │ └── lwShareFix.service (inotifywait 监听) │ │ └── fix-lwshare-names.mjs (自动重命名) │ │ │ │ 宝塔防火墙 ──放行── TCP 60889 │ └──────────────────────┬──────────────────────────────┘ │ ┌──────────────┼──────────────┐ │ │ │ Windows A Windows B Windows C (浏览器) (浏览器) (浏览器) http://IP:60889
|
收尾
记得要把node的默认版本改回原来的node版本,防止影响系统其他服务。