鸿蒙与 Electron 深度融合探索(二):构建跨端协同的“超级终端”原型
作者:L、218
发布平台:CSDN
发布时间:2025年12月2日
🎯 导读:在上一篇文章中,我们用 Electron 模拟了鸿蒙的“服务卡片”UI 风格。本文将更进一步——实现一个具备设备发现、数据流转和状态同步能力的“类超级终端”系统原型。
我们将基于 Electron + WebSocket + Node.js 构建一个多窗口桌面应用集群,模拟鸿蒙 OS 中“手机 → 平板 → 智慧屏”的无缝流转体验。
📌 关键词:鸿蒙分布式理念 | Electron 多实例通信 | 局域网设备发现 | 数据流转动画 | 跨窗口拖拽
一、目标:打造“桌面版超级终端”
✅ 最终效果预览
https://img-blog.csdnimg.cn/direct/9a7e8f3c4d6b4e2a8f1c2b3d4e5f6a7b.gif
动态图说明:
- 左侧为主控制台(Main Hub)
- 右侧为多个“设备窗口”(Device Window)
- 拖动卡片可选择“流转到某设备”
- 流转后原窗口消失,目标窗口显示内容
- 所有设备通过局域网自动发现并注册
二、技术架构设计
+------------------+ +------------------+
| 主控制台 |<----->| 设备窗口 A |
| (Main Hub) | WS | (Device Win A) |
+--------+---------+ +------------------+
|
| 广播发现
v
+------------------+ +------------------+
| 设备窗口 B |<----->| 其他服务模块 |
| (Device Win B) | | (e.g. Web API) |
+------------------+ +------------------+
所有节点使用 UDP 广播进行设备发现,WebSocket 进行实时通信。
三、核心功能实现
第一步:项目结构升级
/harmony-electron-cluster
├── main/
│ ├── app.js # 主进程逻辑
│ ├── network-discovery.js # 网络发现模块
│ └── message-bus.js # 消息总线
├── windows/
│ ├── main-hub.html # 主控制台界面
│ ├── device-window.html # 设备窗口界面
│ └── style.css
├── assets/
│ └── logo-small.png # 小图标用于设备标识
├── preload.js
├── package.json
└── renderer.js # 渲染层通用逻辑
第二步:局域网设备自动发现(UDP广播)
我们使用 dgram 模块实现简易的设备发现协议。
network-discovery.js
const dgram = require('dgram')
const os = require('os')
const BROADCAST_ADDRESS = '255.255.255.255'
const PORT = 44444
const SERVICE_NAME = 'HarmonyElectronNode'
class NetworkDiscovery {
constructor(nodeType = 'unknown') {
this.nodeType = nodeType
this.host = this.getIPAddress()
this.clients = new Set() // 存储已发现的设备
this.socket = dgram.createSocket({ type: 'udp4', reuseAddr: true })
}
getIPAddress() {
const interfaces = os.networkInterfaces()
for (let iface in interfaces) {
for (let alias of interfaces[iface]) {
if (alias.family === 'IPv4' && !alias.internal) {
return alias.address
}
}
}
return '127.0.0.1'
}
startBroadcasting() {
this.socket.bind(() => {
this.socket.setBroadcast(true)
console.log(`[${this.nodeType}] 开始广播...`)
// 每3秒广播一次
setInterval(() => {
const msg = JSON.stringify({
type: 'HELLO',
from: this.host,
name: SERVICE_NAME,
nodeType: this.nodeType
})
this.socket.send(msg, 0, msg.length, PORT, BROADCAST_ADDRESS)
}, 3000)
})
}
startListening(callback) {
this.socket.on('message', (msg, rinfo) => {
try {
const data = JSON.parse(msg.toString())
if (data.from !== this.host && data.type === 'HELLO') {
const clientInfo = { ...data, port: rinfo.port, address: rinfo.address }
this.clients.add(clientInfo.from)
callback(clientInfo) // 回调通知新设备上线
}
} catch (e) {
console.error('解析广播消息失败:', e)
}
})
}
getClients() {
return Array.from(this.clients)
}
}
module.exports = NetworkDiscovery
💡 使用 UDP 广播实现轻量级设备发现,避免中心服务器依赖。
第三步:WebSocket 实时通信总线
message-bus.js
const WebSocket = require('ws')
class MessageBus {
constructor(port = 8080) {
this.port = port
this.server = new WebSocket.Server({ port })
this.clients = new Map() // host -> ws
}
start(onMessage) {
this.server.on('connection', (ws, req) => {
const clientIP = req.connection.remoteAddress.replace(/^.*:/, '')
console.log(`客户端连接: ${clientIP}`)
this.clients.set(clientIP, ws)
ws.on('message', (data) => {
try {
const msg = JSON.parse(data)
onMessage(msg, clientIP, ws)
} catch (e) {
console.error('消息解析错误:', e)
}
})
ws.on('close', () => {
this.clients.delete(clientIP)
console.log(`客户端断开: ${clientIP}`)
})
})
console.log(`消息总线启动于 ws://localhost:${this.port}`)
}
broadcast(message, exclude = null) {
const payload = JSON.stringify(message)
this.clients.forEach((ws, ip) => {
if (ip !== exclude && ws.readyState === WebSocket.OPEN) {
ws.send(payload)
}
})
}
sendTo(ip, message) {
const ws = this.clients.get(ip)
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(message))
}
}
}
module.exports = MessageBus
第四步:主进程整合网络能力 (app.js)
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const NetworkDiscovery = require('./main/network-discovery')
const MessageBus = require('./main/message-bus')
let mainWindow
let deviceWindows = []
let discovery, messageBus
function createMainWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 700,
title: "鸿蒙超级终端 - 控制中心",
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true
}
})
mainWindow.loadFile('windows/main-hub.html')
}
function createDeviceWindow() {
const win = new BrowserWindow({
width: 400,
height: 600,
title: "模拟设备终端",
frame: false,
transparent: true,
alwaysOnTop: false,
resizable: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('windows/device-window.html')
deviceWindows.push(win)
win.on('closed', () => {
deviceWindows = deviceWindows.filter(w => w !== win)
})
return win
}
app.whenReady().then(() => {
createMainWindow()
// 启动网络服务
discovery = new NetworkDiscovery('MainHub')
messageBus = new MessageBus(8080)
messageBus.start((msg, ip) => {
if (msg.type === 'DEVICE_REGISTER') {
console.log(`设备注册: ${ip} (${msg.deviceName})`)
mainWindow.webContents.send('device-online', { ip, name: msg.deviceName })
}
})
discovery.startListening((client) => {
if (client.nodeType === 'DeviceWindow') {
messageBus.sendTo(client.from, { type: 'WELCOME', text: '欢迎加入超级终端!' })
}
})
discovery.startBroadcasting()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createMainWindow()
})
})
// 接收渲染层指令
ipcMain.on('open-device-window', () => {
const win = createDeviceWindow()
win.webContents.on('did-finish-load', () => {
win.webContents.send('init-device', { ip: discovery.host })
})
})
ipcMain.on('transfer-data', (event, payload) => {
const { targetIp, data } = payload
messageBus.sendTo(targetIp, {
type: 'DATA_TRANSFER',
data,
from: discovery.host,
timestamp: Date.now()
})
})
第五步:主控制台 UI (main-hub.html)


四、运行与测试
步骤:
- 安装依赖
npm install electron ws
- 添加启动命令

2.启动主程序
npm start
- 点击 “打开模拟设备” 创建多个设备窗口
- 拖动卡片选择目标设备完成“流转”
五、总结:我们实现了什么?
| 鸿蒙特性 | 本项目实现程度 | 技术手段 |
|---|---|---|
| 设备发现 | ✅ 自动识别局域网内节点 | UDP广播 |
| 数据流转 | ✅ 卡片内容跨窗迁移 | WebSocket |
| 多端协同 | ✅ 多窗口状态联动 | 消息总线 |
| 分布式调度 | ⚠️ 原型级支持 | 主从架构模拟 |
| 性能体验 | ❌ 存在延迟 | Chromium 开销 |
🎯 这不是真正的鸿蒙,但它是理解鸿蒙思想的一扇窗。
六、未来展望
- 接入真实鸿蒙设备 API(如开放 HTTP 接口)
- 结合 TSC + Vite 提升开发体验
- 引入 AI 能力实现智能流转决策
- 打包为独立桌面应用,支持开机自启
结语
“真正的创新,往往始于对未来的模仿。”
鸿蒙所描绘的“万物互联”愿景,正在激励无数开发者用现有技术去逼近那个理想世界。而 Electron,正是我们手中最趁手的工具之一。
希望这个“伪超级终端”项目,能为你带来启发。
获取源码
GitHub 地址:https://github.com/L218/harmony-electron-super-terminal
欢迎 Star ⭐ | Fork 🔁 | 提交 Issue 💬
📢 关注 @L、218,持续输出鸿蒙 × 前端 × 跨端开发实战系列文章!
💬 评论区互动:你希望下一个功能是“音频流转”还是“剪贴板同步”?留言告诉我!
本文原创,转载请注明出处。
更多推荐



所有评论(0)