2a641b1eff0eaaf523fb1776a51a8449a57ee548
## USB 整体下线 把 USB 功能真删掉, 不是只藏 UI: - 删 `src/main/remote/usb.ts` + `src/renderer/src/components/remote/UsbPanel.vue` - 删 `usb` (node-usb) 和 `node-hid` 两个依赖 —— 查过, 本来就没被真正用起来 - `asarUnpack` 去掉 node-usb/usb/node-hid 的规则 - ChatView 的 tab 由 "USB" 改成 "串口" ## 串口映射 + 串口助手 (新) `src/main/remote/serial.ts` (取代 usb.ts) 只做串口, 一个文件两件事: - **串口映射**: 把一端的真实串口映射成另一端可用的虚拟串口 (Linux/macOS 用 socat 建 PTY 配对, Windows 用 com0com 建 COM 对)。 方向做成 "我用对方的" / "对方用我的" 两种, 两边都能发起。 - **串口助手**: 不建虚拟口时, 应用自己当助手 —— 字节流直接显示, 能发文本/HEX, 能追加 LF, 能循环发送, 能清屏/存日志。 `src/renderer/src/components/remote/SerialPanel.vue` (新) 把两者做在一个面板里: 设备表 (串口 / VID:PID / 产品 / 制造商)、串口参数 (波特率/数据位/停止位/校验)、 TX/RX 时间戳 + hex + ascii 视图、虚拟口路径横幅 (可一键复制)。 ## 串口助手要能调 Linux Linux 上调串口最常见的两个坑, 都做成产品功能: - **没权限**: 诊断 dialout 组 + socat + 串口列表, 一键提权修复 (`sudo usermod -aG dialout $USER`, 提示要重新登录才生效)。 "设备没插" 和 "没权限" 分开报错, 不再混成一句 "打开失败"。 - **缺 socat**: 建虚拟口前先探 socat, 没有就弹安装指引 (apt/dnf), 免得 attach 做到一半才失败。 平台化文案也分开了: Linux 提示 dialout, Windows 提示设备管理器, macOS 提示隐私授权。 ## 线上格式一个字节没动 (兼容性关键) 局域网里常有一台机器跑旧版本, 所以: - `PROTOCOL_VERSION` 仍然 = 1 - WS 帧类型仍然叫 `'usb'` - 只把内部类型改名 (`SerialDeviceInfo` / `SerialAttachConfig` / ...) 代价: 混版本时已下线的 USB 字节桥不可用。换来: 新旧版本聊天照常, 串口映射也照常, 不会因为升协议被踢下线。**别手贱顺手改对** (AGENTS.md 坑 #10)。 ## 其它 - 主进程 `output` 事件带方向 (rx/tx), 助手才能分清"我发的"和"设备回的"; 客户端自己发出的字节不回显成 rx (无回环, S5 用例守住) - 虚拟串口 (vcom) 模式下 app 不读内部端, 避免和 socat 抢数据 - `src/main/permissions.ts` 重写成串口专用, 删掉 USB/HID 相关诊断与修复 - 保留 `src/main/remote/vcom.ts` (socat/com0com 配对) 不动, 与 serial.ts 分离 ## 验证 - npm run typecheck ✅ - npm run selftest ✅ 79 通过 / 0 失败 (USB 用例整体换成 S1-S9 串口用例) - npm run build ✅ - npm run package:linux ✅ 新 deb (84MB) - npm run selftest:package ✅ 4/4 (改成校验 serialport 原生绑定已解包) 真机 (CDP 驱动真实窗口) 验证过: 串口 tab 能打开, 设备表列到 32 个 /dev/ttyS*, 助手区 + hex 区在, 波特率/数据位/停止位/校验/循环发送/清屏/保存日志 按钮齐全, 方向切换会换设备列表 (我用对方的 = 对方设备, 对方用我的 = 本机设备)。
LocalNetMsg
局域网即时通讯工具,飞书/微信聊天风格。基于 Electron + Vue 3 + TypeScript。
功能
- 局域网自动发现 (UDP 广播)
- 1 对 1 私聊,消息持久化 (SQLite)
- 富文本消息:Markdown / 代码高亮 / @提醒 / 表情
- 图片消息:粘贴板、拖拽、本地选择
- 文件传输:任意类型,大文件流式上传
- 飞书式三栏 UI,消息气泡、时间分组、发送状态
- 系统托盘最小化,后台新消息系统级通知
- 接收文件按
设置目录/YYYY-MM/自动归档
开发
环境要求: Node.js >= 20
npm install
npm run dev # 启动 Electron + 热更新
第一次启动时:
- 默认接收目录:
~/Documents/LocalNetMsg - 默认设备名: 操作系统主机名
- 两个端口自动分配 (UDP 发现 47800 / WebSocket 47900 / 文件 47901)
要测试多设备,在同一局域网的不同机器上各跑一个实例即可。
项目结构
src/
├── main/ Electron 主进程
│ ├── index.ts 入口: 窗口、托盘、IPC
│ ├── discovery.ts UDP 局域网发现
│ ├── chat-server WebSocket 服务端
│ ├── chat-client WebSocket 客户端
│ ├── file-server HTTP 文件服务
│ ├── db.ts SQLite 持久化
│ ├── settings.ts electron-store
│ ├── notify.ts 系统通知
│ └── protocol.ts 消息协议定义
├── preload/ contextBridge 桥接
└── renderer/ Vue 3 渲染层
├── src/
│ ├── views/ ChatView, SettingsView
│ ├── components/ Sidebar, MessageList, MessageItem, MessageInput
│ ├── stores/ Pinia
│ ├── api/ IPC 桥接
│ └── utils/ markdown, format
└── index.html
配置
~/AppData/Roaming/local-net-msg/config.json (electron-store):
deviceName: 本机在网络中的显示名downloadDir: 接收文件保存目录notifications: 是否启用系统通知
端口
| 用途 | 端口 | 协议 |
|---|---|---|
| 局域网发现 | 47800 | UDP |
| 聊天 | 47900 | WebSocket |
| 文件传输 | 47901 | HTTP |
被占用时自动顺延。
Description
Languages
TypeScript
70.8%
Vue
23.6%
JavaScript
5.3%
CSS
0.2%