news 2026/9/13 18:59:02

Neko 路线图解析:从 V3 服务器迁移、客户端重写到模块化架构

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Neko 路线图解析:从 V3 服务器迁移、客户端重写到模块化架构

Neko 路线图解析:从 V3 服务器迁移、客户端重写到模块化架构

【免费下载链接】nekoA self hosted virtual browser that runs in docker and uses WebRTC.项目地址: https://gitcode.com/GitHub_Trending/ne/neko

Neko 是一个运行在 Docker 中、基于 WebRTC 的自托管虚拟浏览器项目,其官方路线图(webpage/docs/roadmap.md)将未来发展划分为三个阶段:V3 服务器迁移、V3 客户端重写、整体模块化。本文以该路线图为骨架,结合当前仓库中的服务端、客户端源码与配置实现,逐阶段拆解每个规划的技术内涵、当前落地状态与后续演进方向,帮助读者理解 Neko 的架构演进逻辑,以及连接、媒体流、控制三大抽象层的设计思路。

路线图总览:三个阶段

路线图将 Neko 的发展划分为三个彼此衔接的阶段,每一阶段聚焦项目的一个侧面:

  • Phase 1 – Server migration to V3:完成服务端向 V3 的迁移与整合,已随 Neko V3.0.0 发布而完成;
  • Phase 2 – Client rewrite to V3:将基于 Vue2 的客户端重写为基于 Vue3 的组件化客户端;
  • Phase 3 – Modularization:将 V3 客户端与服务端模块化,把连接、媒体流、控制抽取为可替换的接口层。

从仓库结构看,这三个阶段并非彼此割裂:服务端server/internal/下的api/capture/http/legacy/webrtc/websocket/等模块,以及客户端client/src/下的neko/store/components/,共同构成了路线图所描述的现状基础。

Phase 1:V3 服务器迁移与 V2 兼容层

服务器合并与 V3.0.0 发布

Phase 1 的目标是完成服务端迁移,其成果随 Neko V3.0.0 发布而落地。原 m1k1o/neko 服务器与已归档的 demodesk/neko 服务器被合并,并在此基础上发布了新的 V3.0.0 版本。合并的目的在于统一两套代码遗产、收敛维护精力,同时为后续的客户端重写与模块化提供稳定的服务端基础。

V2 客户端兼容层:legacy 模块

路线图明确指出,Phase 1 中"添加了一个兼容层以支持 V2 客户端"。在仓库中,这一兼容层对应server/internal/http/legacy/目录(handler.go 等)。

从源码看,LegacyHandler采用"协议翻译代理"模式实现兼容:

  • 对外暴露 V2 时代的 HTTP/WebSocket 端点,例如/ws/stats/screenshot.jpg/file(支持 GET/POST/DELETE)、/health(handler.go);
  • 收到 V2 客户端连接后,通过wsDialer.Dial("ws://"+serverAddr+"/api/ws?token=...")回连到 V3 后端(handler.go);
  • 通过两个 goroutine 双向复制 WebSocket 消息(replicateWebsocketConn),并在wsToClient/wsToBackend中对新旧消息格式做改写(handler.go)。

这意味着 V2 老客户端无需改动即可继续访问 V3 服务端,为 V3 上线提供了平滑过渡路径。

配置层面的 V2 → V3 迁移

与兼容层配套,服务端保留了完整的 V2 配置兼容逻辑。以 WebRTC 配置为例,server/internal/config/webrtc.go 中同时存在Init/Set(V3 命名空间)与InitV2/SetV2(V2 旧命名空间):

  • V3 配置形如NEKO_WEBRTC_ICELITENEKO_WEBRTC_ICESERVERS_FRONTENDNEKO_WEBRTC_EPR等;
  • V2 配置形如NEKO_ICELITENEKO_ICESERVERSNEKO_EPR等,一旦被检测到,代码会打印弃用警告并自动启用legacy标志(webrtc.go)。

视频捕获配置同样如此:server/internal/config/capture.go 中 V2 的NEKO_VIDEO_CODECNEKO_HWENCNEKO_VIDEO_BITRATENEKO_MAX_FPS会被转换为 V3 的NEKO_CAPTURE_VIDEO_*管线配置,并通过NewVideoPipeline自动生成 GStreamer 管线(capture.go)。这种"新旧并存、自动降级"的设计,保证了从 V2 到 V3 的配置迁移成本可控。

Phase 2:V3 客户端重写(Vue2 → Vue3)

重写动机:Vue2 生命周期结束

路线图指出,V2 客户端基于 Vue2 构建,而 Vue2 早已到达生命周期终点(EOL)。当前仓库的 client/package.json 中依赖仍为"vue": "^2.7.13"vue-class-componentvue-property-decoratorvuex等 Vue2 生态组件,这正印证了路线图所述的现状——V2 客户端仍是当前实现。

从"界面导向"到"组件导向"的设计转变

路线图明确对比了两代客户端的设计哲学:

  • V2 客户端聚焦用户界面(user interface):当前client/src/components/下的connect.vuevideo.vuemenu.vueside.vuecontrols.vuemembers.vuechat.vueclipboard.vue等组件即为此类 UI 呈现;
  • V3 客户端聚焦可扩展性(extensibility in the form of components):客户端将被拆分为可无缝嵌入任意现有应用的组件,这些组件可以在任何其他 Vue3 应用中被复用;对传统用户而言,客户端仍会以独立应用形式提供全部既有功能。

仓库中已经能看到组件化方向的雏形:client/src/lib.ts 通过build:lib脚本(vue-cli-service build --target lib --name neko-lib 'src/lib.ts')将客户端构建为库,并导出了NekoConnectNekoVideoNekoMenuNekoSideNekoControlsNekoMembersNekoChatNekoClipboard等一系列可独立引用的组件(package.json,lib.ts)。这就是"组件可用于任何 Vue3 应用"理念在当前代码中的最早落地。

Phase 3:模块化——连接、媒体流与控制三抽象

Phase 3 是路线图中着墨最多的部分。其核心设想是:V3 客户端将被拆分成一个不依赖 Vue.js(甚至不依赖任何库)的 TypeScript 组件库,任何项目都可以像嵌入一个视频播放器那样轻松集成 Neko,参考 demodesk/neko-client 的构建思路,但去掉 Vue.js 依赖。同时,连接(connection)、媒体流(media streaming)、控制(control)将被提取为接口,使 Neko 从"共享虚拟环境"升级为"内置反馈与带外通信工具的视频流服务器"——例如原生绑定 RDP/VNC 协议、远程控制无人机/机器人/PTZ 摄像头/工业设备等。由于控制层可以是插件,输入源也不再局限于键盘鼠标,还可接入游戏手柄、摇杆甚至 VR 眼镜。

Connection:面向 API 用户的连接抽象

路线图要求:Neko 可以通过多种通道连接后端,因此API 用户不应暴露于 WebSocket 内部细节,只需要关心两类信息:

连接状态(connection status):

状态含义
connected用户已连接服务器
connecting客户端正在尝试建立连接
disconnected用户已断开且无重连尝试,必须携带断开原因

连接类型(connection type):

类型机制
none当前未使用任何连接
short_polling每隔 X ms 客户端请求一次服务器获取更新
long_pollingHTTP 请求保持打开,直到服务器有更新下发,随后客户端再发起新请求
sse服务器通过 Server-Sent Events 向客户端推送更新
websocket服务器通过 WebSockets 推送更新
...其他,例如 MQTT

当前实现中,连接状态机已存在于客户端基类 client/src/neko/base.ts:

  • socketOpen判断 WebSocket 是否打开,peerConnected判断 WebRTC ICE 状态是否处于connected/checking/completed,二者同时满足才认为整体connected(base.ts);
  • 事件处理中区分了EVENT.CONNECTINGEVENT.CONNECTEDEVENT.DISCONNECTED(reason),其中onDisconnected会接收reason?: Error参数(base.ts),与路线图"断开必须携带原因"的要求一致;
  • 客户端状态在 Vuex store 中维护connecting/connected布尔状态(client/src/store/index.ts)。

这也解释了路线图为何要求抽取连接接口:当前BaseClient将 WebSocket(信令、控制消息)与 WebRTC(媒体、数据通道)深度耦合,一旦接入 MQTT 或 SSE 通道,就必须在接口层将这些细节隐藏起来。

Media streaming:单一接口下的多流后端

路线图对媒体流提出了与连接层对称的抽象,计划支持的流媒体后端包括:

流后端机制
none当前无媒体流
m3u8通过 HLS 传输媒体
webrtc通过 WebRTC 传输媒体
quic通过 QUIC 传输媒体
...其他,例如 RTSP、DASH

不同的流媒体后端具备不同能力:例如 WebRTC 支持"向服务器发送媒体"(麦克风上行),而 HTTP 系只能单向接收。流后端的选择可基于用户设备能力、网络条件、服务器能力综合决定。所有流后端必须满足同一个接口,该接口是与系统其他部分通信的唯一通道

仓库当前的多流支持已经为这一抽象奠定了基础:

  • server/internal/config/capture.go 支持配置多个视频管线NEKO_CAPTURE_VIDEO_PIPELINESmap[string]VideoConfig)与有序视频 ID 列表NEKO_CAPTURE_VIDEO_IDS,也可用NEKO_CAPTURE_VIDEO_PIPELINE快捷配置单管线;未配置时使用默认 VP8 管线(capture.go);
  • server/internal/capture/streamselector.go 实现了StreamSelectorManagerCtx流选择器,支持按流 ID(exact/lower/higher)和按码率(nearest/lower/higher/exact)选择当前使用的流,并带有nearestBitrate最近码率匹配逻辑(streamselector.go);
  • 服务端 WebRTC 带宽估计器(webrtc.estimator.*系列配置,见 server/internal/config/webrtc.go)会根据估计带宽自动在高低码率流之间升级/降级,其read_intervalstable_durationunstable_durationdiff_threshold等参数正是"基于网络条件选择流"的工程实现。

路线图中"单一接口"的设计目标,与当前StreamSinkManager/StreamSelector的抽象方向是一致的——未来的 m3u8/quic 后端可以挂到同一接口之下。

Control(人机接口设备):带内与带外反馈

控制层是 Phase 3 中最具想象力的部分。路线图设想用户可使用键盘、鼠标、游戏手柄、触摸屏或任何其他可控制系统的设备,也支持自定义或虚拟设备。控制数据的反馈分为两种模式:

  • 带内反馈(in-band):正常情况下,反馈直接在媒体流内呈现给用户(例如画面本身);
  • 带外反馈(out-of-band):在特定场景下必须走独立通道,包括:
    • 游戏手柄的振动反馈
    • 光标在屏幕上被隐藏,或针对特定用户隐藏,因此光标需要带外传输
    • 多用户场景下,所有人可在屏幕上看到各自的自定义光标,但只有一人能实际控制光标,因此光标位置必须带外传输
    • 修改屏幕分辨率、方向或其他设置;
    • 修改键盘布局或修饰键;
    • 设置 host(根据优先级与权限决定当前控制者)。

控制数据既可以通过底层连接传输,也可以通过媒体流通道传输——例如WebRTC data channel 可用于实时传输控制数据

当前实现恰好展示了"带外光标"与"数据通道控制"的雏形:

  • server/internal/webrtc/handler.go 处理 WebRTC DataChannel 上到达的二进制控制协议:OP_MOVE移动事件中,host 用户移动真实光标(manager.desktop.Move+curPosition.Set),非 host 用户仅更新自己的会话光标位置(session.SetCursor),这与路线图"只有一人控制光标、所有人光标位置带外传输"完全吻合(handler.go);此外还处理OP_SCROLL、键盘按键(KEY_DOWN/KEY_UP)与OP_PING/OP_PONG心跳(handler.go);
  • 客户端侧 client/src/neko/base.ts 的sendData用二进制帧封装鼠标移动(OPCODE.MOVE)、滚轮(OPCODE.SCROLL)、按键按下/抬起,通过this._channel.send(buffer)走 RTCDataChannel 发送;
  • 服务端server/internal/webrtc/cursor/(image.go、position.go)独立维护光标图像与位置,client/src/neko/index.ts 中EVENT.CONTROL.LOCKED/EVENT.CONTROL.RELEASE分别响应 host 的取得与释放,配合键盘布局切换(remote.changeKeyboard()),正是"设置 host"与"键盘布局带外同步"的现有实现。

路线图的演进价值

综合来看,Neko 的路线图描绘了一条清晰的架构演进路径:

  1. 兼容优先:Phase 1 通过合并服务器 + 协议代理兼容层(server/internal/http/legacy/)+ V2 配置自动迁移(webrtc.go/capture.goInitV2/SetV2),在不中断老用户的前提下完成服务端换代;
  2. 体验升级:Phase 2 借 Vue2 EOL 之机,把以界面为中心的客户端重构为以组件为中心的可嵌入式客户端(client/src/lib.ts已是第一步);
  3. 能力泛化:Phase 3 将连接、媒体流、控制三者的接口彻底解耦,使 Neko 从"共享浏览器"泛化为通用的低延迟远程控制与视频流基础设施,输入设备与传输协议均可按插件化方式扩展。

对开发者而言,如果希望参与 Neko 的后续演进,可以从三个切入点着手:研究 server/internal/http/legacy/ 理解协议兼容层的实现模式;阅读 client/src/neko/base.ts 与 client/src/lib.ts 评估 Vue3 客户端重写的工作量;以及围绕 server/internal/webrtc/handler.go 与 server/internal/capture/streamselector.go 思考新流后端与控制设备插件应如何接入统一接口。

【免费下载链接】nekoA self hosted virtual browser that runs in docker and uses WebRTC.项目地址: https://gitcode.com/GitHub_Trending/ne/neko

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 18:57:15

烧录地址的本质:芯片启动时的硬件寻址逻辑

1. 烧录地址不是“乱填的数字”,而是芯片启动逻辑的物理指纹 你第一次在Keil里点“Download”时,烧录器弹出窗口里那个地址栏——0x08000000、0x6000、0x0000……你是不是下意识就照着例程抄?抄完程序跑起来了,松一口气&#xff1…

作者头像 李华
网站建设 2026/9/13 18:55:35

C++物业管理系统代码剖析:面向对象、文件持久化与数据校验

简介:C物业管理系统是一份完整的课程设计与实战项目资源,适合学习C面向对象编程、文件读写、GUI开发及数据库应用的开发者参考。压缩包共99个文件,包含32个cpp源文件、31个头文件、29个ui界面文件,另有sql数据库脚本、Qt工程配置与…

作者头像 李华
网站建设 2026/9/13 18:54:47

小体积高扭矩电机驱动:通用MCU与硅MOS方案的优化和取舍

做电机驱动的朋友应该都碰到过类似的问题:明明方案也是FOC、也是MCU加MOS管,凭什么别人家的板子又小扭矩又大,自己的板子要么很大,要么一猛起就发烫?早几年我折腾无人机电调、电动工具和机器人关节的时候,被…

作者头像 李华
网站建设 2026/9/13 18:54:45

PMSM电机FOC控制全解析:从坐标变换到无感调试

FOC在圈里被吹得神乎其神,但也确实劝退了很多人。早几年我刚开始碰PMSM无感控制的时候,光看那堆坐标变换的公式推导就想摔键盘。后来真正把代码跑起来、把波形调出来,回头看才发现,FOC没有那么玄乎,但也绝不是一个晚上…

作者头像 李华