aiDgeScanner 技术文档
目录
- [1. 项目概述](#1. 项目概述)
- [2. 系统架构](#2. 系统架构)
- [3. 核心模块详解](#3. 核心模块详解)
- [4. 数据流程](#4. 数据流程)
- [5. 配置说明](#5. 配置说明)
- [6. 扩展开发](#6. 扩展开发)
1. 项目概述
1.1 项目简介
aiDgeScanner 是一款基于 Electron + Vue 3 + C++ NAPI 的跨平台工业设备网络扫描与管理工具。该工具能够自动发现网络中的工业设备,并提供 SSH 远程登录、Web 配置等功能。
1.2 技术栈
| 层级 | 技术 | 版本 | 用途 |
|---|---|---|---|
| 桌面框架 | Electron | ^39.8.1 | 跨平台桌面应用 |
| 前端框架 | Vue | ^3.5.0 | UI 组件化开发 |
| 构建工具 | Vite | ^5.0.0 | 快速打包开发 |
| 终端模拟器 | xterm.js | ^6.0.0 | SSH/Terminal 渲染 |
| SSH 库 | ssh2 | ^1.17.0 | SSH 协议实现 |
| 原生插件 | node-addon-api | ^8.0.0 | C++/Node.js 互操作 |
| 网络抓包 | libpcap | - | 原始报文捕获 |
2. 系统架构
2.1 整体架构图
系统层
libpcap
系统 API
C++ NAPI 插件
设备扫描器
LLDP 解析器
报文捕获
设备管理
主进程 (Node.js)
main.js (主入口)
SSH 连接管理
设备扫描器
窗口管理
Context Bridge
preload.js
UI 层 (Vue 3)
App.vue (主应用)
SSHTerminal.vue (SSH 终端)
TelTerminal.vue (Telnet 终端)
SettingsModal.vue (设置)
SSHLoginModal.vue (SSH登录)
2.2 进程模型
"C++ NAPI" "主进程" "Preload 脚本" "渲染进程" "C++ NAPI" "主进程" "Preload 脚本" "渲染进程" API 调用 IPC 消息 原生调用 结果返回 IPC 响应 回调执行
3. 核心模块详解
3.1 设备扫描模块
3.1.1 LLDP 协议实现
LLDP (Link Layer Discovery Protocol) 是 IEEE 802.1AB 标准定义的链路层发现协议。
LLDPAgent
-chassisId
-portId
-ttl
+receive()
+parse()
+extractTLV()
TLVParser
+parseChassisId()
+parsePortId()
+parseManagementAddr()
+parseSystemName()
关键实现点:
- 原始以太网帧捕获:使用 libpcap 捕获包含 LLDP 报文的帧
- TLV 解析:Type-Length-Value 结构解析
- 设备信息提取:MAC、IP、主机名等
3.1.2 UDP 发现协议
自定义 UDP 广播发现协议,用于主动扫描网络设备。
"设备" "网络" "aiDgeScanner" "设备" "网络" "aiDgeScanner" 发送 UDP 查询报文 解析响应并更新设备列表 广播 UDP (端口 6000) 转发 响应 UDP 报文 转发响应
报文格式:
[设备类型 (1B)][MAC (6B)][IP (4B)][主机名 (可变)]
3.1.3 设备扫描器 API
javascript
// 初始化
const scanner = new DeviceScanner({
queryInterval: 5, // 查询间隔(秒)
lldpEnabled: true, // 启用 LLDP
udpEnabled: true, // 启用 UDP
interfaceName: 'eth0', // 监听网卡
udpPort: 6000 // UDP 端口
})
// 事件监听
scanner.on('device', (info) => {
console.log('发现设备:', info)
})
// 启动/停止
scanner.start()
scanner.stop()
3.2 SSH 终端模块
3.2.1 架构设计
SSHTerminal.vue
xterm.js (渲染)
ipcRenderer (通信)
main.js (主进程)
ssh2 (协议实现)
远程服务器
3.2.2 关键实现
主进程 SSH 连接管理:
javascript
// 创建 SSH 连接
const sshConn = new Client()
sshConn.connect({
host: hostname,
port: port,
username: username,
password: password
})
// 处理 Shell 流
sshConn.shell((err, stream) => {
// 输出转发到 xterm
stream.on('data', data => {
mainWindow.webContents.send('terminal-output', {
terminalId,
output: data.toString()
})
})
})
终端交互流程:
用户输入
xterm.js 捕获
ipcRenderer 发送
主进程接收
写入 SSH 流
远程设备执行
输出返回
发送到渲染进程
xterm.js 渲染
用户查看
3.3 IPC 通信模块
3.3.1 IPC 事件列表
| 事件名 | 方向 | 用途 |
|---|---|---|
message |
R→M | 通用消息通道 |
terminal-input |
R→M | 终端输入发送 |
terminal-output |
M→R | 终端输出渲染 |
device:update |
M→R | 设备更新通知 |
ssh-status |
M→R | SSH 连接状态 |
3.3.2 Context Bridge
通过预加载脚本安全暴露 API:
javascript
// preload.js
contextBridge.exposeInMainWorld('electronAPI', {
sendMessage: (msg, data) => ipcRenderer.send('message', msg, data),
onMessage: (channel, callback) => ipcRenderer.on(channel, (_, ...args) => callback(...args)),
sendTerminalInput: (data) => ipcRenderer.send('terminal-input', data)
})
contextBridge.exposeInMainWorld('scannerAPI', {
start: () => ipcRenderer.invoke('scanner:start'),
stop: () => ipcRenderer.invoke('scanner:stop'),
getDevices: () => ipcRenderer.invoke('scanner:getDevices'),
listInterfaces: () => ipcRenderer.invoke('scanner:listInterfaces'),
onDevice: (callback) => ipcRenderer.on('device:update', (_, info) => callback(info)),
restartScanner: (settings) => ipcRenderer.invoke('scanner:restart', settings)
})
3.4 主题系统
3.4.1 主题架构
主题选择器
CSS 变量切换
Golden Osmanthus
Bamboo Green
Bright Moon
Sea Blue
Rich Silver
实时应用
3.4.2 CSS 变量设计
css
:root {
--primary-color: #d4a017; /* 主色 */
--secondary-color: #b8860b; /* 次色 */
--text-color: #333; /* 文字色 */
--text-secondary: #666; /* 次要文字色 */
--bg-color: #fffaf0; /* 背景色 */
--surface-color: #fff8dc; /* 表面色 */
--border-color: #daa520; /* 边框色 */
}
3.5 多语言系统
3.5.1 国际化架构
用户选择语言
setLocale()
加载翻译资源
t() 函数响应
Vue 组件重新渲染
界面更新
3.5.2 资源结构
javascript
// i18n/index.js
const messages = {
zh: {
app: {
title: '设备扫描器',
scan: '开始扫描',
settings: '设置',
ssh: 'SSH',
configPage: '配置页面'
}
},
en: {
app: {
title: 'Device Scanner',
scan: 'Start Scan',
settings: 'Settings',
ssh: 'SSH',
configPage: 'Config Page'
}
}
}
4. 数据流程
4.1 设备发现完整流程
开始扫描
初始化设备扫描器
开始监听网络
捕获数据包
解析协议 (LLDP/UDP)
提取设备信息
更新设备列表
通知渲染进程
渲染 UI 显示
4.2 SSH 连接建立流程
"SSH 服务器" "主进程" "渲染进程" "用户" "SSH 服务器" "主进程" "渲染进程" "用户" 点击 SSH 按钮 发送 openSSH 消息 初始化 ssh2 连接 TCP 连接请求 握手响应 用户认证 认证成功 创建 Shell 会话 发送连接就绪 显示终端 输入命令 terminal-input 事件 写入 Shell 流 输出结果 terminal-output 事件 xterm.js 渲染
4.3 设置保存与应用流程
用户修改设置
保存到 localStorage
发送到主进程
重启设备扫描器
应用新配置
新设置生效
5. 配置说明
5.1 项目配置文件
package.json 配置
json
{
"name": "devscan",
"version": "1.0.0",
"main": "main.js",
"build": {
"appId": "com.devscan.app",
"productName": "DevScan",
"directories": {
"output": "release"
},
"npmRebuild": false,
"win": {
"target": ["nsis", "portable"]
}
}
}
5.2 运行时配置
设备扫描配置项
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
listenMode |
枚举 | both |
监听模式 (both/lldp/udp) |
networkInterface |
字符串 | 首个网卡 | 监听网卡名称 |
udpPort |
数字 | 6000 |
UDP 监听端口 |
queryInterval |
数字 | 5 |
查询间隔(秒) |
6. 扩展开发
6.1 添加新的协议支持
- 在
native/src/目录创建新的协议解析器 - 在
scanner.cc中集成协议处理 - 在
main.js中添加对应 API - 在前端添加协议选择配置
6.2 添加新主题
- 在
src/theme/theme.css中添加新的 CSS 变量 - 在
src/theme/index.js中添加主题切换函数 - 在
App.vue中添加主题选项
6.3 添加新语言
- 在
src/i18n/index.js中添加翻译对象 - 在
App.vue中添加语言选择项 - 确保所有文本使用
t()函数
附录
A. 故障排查
A.1 libpcap 相关问题
Windows 系统需要安装 Npcap,Linux 需要 sudo apt-get install libpcap-dev
A.2 SSH 连接问题
确认 ssh2 库安装:npm install ssh2
检查网络连接和端口开放情况