
OpenNOW核心协议参考Qt与Rust核心间带版本JSON RPC通信完整指南【免费下载链接】OpenNOWCustom GeForce Now Client Named OpenNOW项目地址: https://gitcode.com/gh_mirrors/op/OpenNOWOpenNOW 是一款社区开发的开源 GeForce NOW 云游戏客户端。它的核心协议是一套运行在 QtC外壳与 Rust 应用核心之间的带版本 JSON RPC 通信机制以换行分隔的 UTF-8 JSON 消息走标准输入/输出靠core.hello握手完成协议版本协商再用 request / response / event / cancel 四种消息类型驱动登录、商店、云游戏会话等全部功能。本文带你从零读懂这套协议的设计与实现。一眼看懂架构Qt 画界面Rust 干重活OpenNOW 桌面版被拆成两个独立进程角色技术负责内容Shell外壳Qt Quick / C所有窗口、场景图、视频项、输入Core核心Rust 独立进程账号认证、商店目录、云匹配会话、设置持久化两者的全部对话都由 Qt 侧的 CoreClient 类封装——它负责拉起 Rust 核心进程、写入消息、解析 stdout、管理超时与重试。同一个应用还支持手柄驱动的主机模式布局切换布局不需要换进程UI 与核心的 JSON RPC 通信方式完全一致。传输层标准流上的换行 JSON协议刻意选择了最简单的载体通道核心进程继承Qt 的 stdin/stdout一行一条 JSON 消息stderr 单独保留给脱敏诊断日志硬限制单条消息上限1 MiB未知类型、格式错误或超长的消息会直接让核心连接转入failed而不是把外壳留在模糊状态常量即契约Qt 侧把这三个边界写成了类常量一眼可见CoreClient.h 中定义了CurrentProtocolVersion 1、MaximumLineBytes 1024 * 1024、MaximumQueuedEvents 512Rust 侧在 main.rs 中声明PROTOCOL_VERSION: i64 1。两端版本号必须在握手时互相验证。握手与版本协商core.hello 必须第一个到核心协议的第一条规则外壳的第一条请求永远是core.hello在此之前不发任何产品请求。{type:request,id:1,method:core.hello,params:{protocolVersion:1,shell:qt,shellVersion:0.5.4}}Qt 在核心进程started信号触发后立即发出这条握手请求超时设为5 秒见 CoreClient.cppRust 侧的分派逻辑则直接比对版本号不一致就返回incompatible_protocol错误见 main.rs{type:response,id:1,ok:true,result:{protocolVersion:1,coreVersion:1.0.0,capabilities:[settings,gfn.deviceAuth,catalog.storePages.v1,nativeStreamer.v7,osCredentialStore,mediaLibrary, ...]}}这个响应携带的capabilities 数组就是核心的能力清单——商店分页、本地目录、原生流媒体 v7、系统凭据库等都逐一列出外壳可据此决定功能开关。握手的失败面被设计得很窄但很明确版本不匹配、5 秒超时、进程退出、数据非法任何一种都会把传输层转入failed并附上不含凭据的诊断信息。四种消息类型request / response / event / cancel握手的消息信封就是全部协议{type:request,id:42,method:settings.get,params:{}} {type:response,id:42,ok:true,result:{settings:{}}} {type:response,id:42,ok:false,error:{code:invalid_setting,message:…}} {type:event,name:settings.changed,payload:{key:fps,value:120}} {type:cancel,id:42}各类型职责request外壳发起调用id在核心进程内唯一每个请求都有有界截止期100 ms 到 5 分钟response按id对应回请求ok:true带resultok:false带error{code, message}event核心主动推送如settings.changed、updater.changed通过最多512 条的队列批量投递队列满时丢弃最旧事件并累加诊断计数器cancel超时或被用户取消时外壳发送取消已取消的请求会抑制其后续响应可靠性机制busy 重试、指数退避与协作式取消协议对核心太忙有一整套优雅降级策略核心最多接受8 个 RPC worker其中 4 个留给catalog.*、artwork.*、network.regions.ping等后台任务超量请求直接返回busy重复的活动 ID 同样被拒绝Qt 客户端收到busy后不报错而是保留同一 ID 和载荷100 ms 后重试延迟翻倍至多到 1 秒且不延长原始截止期退避逻辑见 CoreClient.cpp取消只在协作检查点生效商店翻页、区域测速循环会停下来但已经在跑的 HTTP/DNS/TCP 不会被硬中断其原有超时继续生效这套机制保证 UI 永远不会因核心忙而卡死也不会因盲目重试放大负载。方法目录所有功能都是 RPC协议 1 版本已实现的方法覆盖全部产品能力按前缀分组一目了然完整清单见 docs/core-protocol.md前缀代表方法用途auth.*auth.device.start/auth.accounts.switch设备码登录、多账号管理catalog.*catalog.store.list/catalog.store.local商店游标分页、本地目录搜索session.*session.create/session.claim/session.poll云游戏会话创建、断线重连streamer.*streamer.prepare/streamer.start原生流媒体准备与启动updater.*updater.check/updater.install应用自更新settings.*/diagnostics.*settings.get/diagnostics.export设置读写与脱敏诊断导出失败策略清晰的 failed 状态与自动重启核心协议刻意不做将错就错坏 JSON、未知消息类型、超尺寸行都会触发protocolFailure一次性失败所有挂起请求进程意外退出则走failAll 自动重启路径重启预算耗尽前会持续尝试拉起核心。Qt 侧由此形成一个简单的状态机stopped → starting → handshaking → ready ↘ 协议/进程异常 ↗ failed随后自动重试启动对普通用户来说这意味着核心闪退后应用会自愈对开发者来说这意味着任何协议破坏都会快速失败而不是留下一个半死不活的连接。延伸阅读3 个必读源码文件想深入核心协议的细节建议按顺序阅读协议规范行为契约的权威来源docs/core-protocol.mdQt 客户端实现进程管理、握手、超时、退避opennow-qt/src/core/CoreClient.cppRust 核心分派版本校验、方法路由、capabilitiesnative/opennow-core/src/main.rs小结OpenNOW 的核心协议用换行 JSON 版本号握手 有界队列 busy 退避这套朴素而严谨的组合在 Qt 外壳与 Rust 核心之间建立了一条可测试、可恢复、可演进的 RPC 通道——协议版本 1 的所有扩展商店分页、本地目录、更新器都以附加能力方式声明不破坏握手契约这正是它值得借鉴的地方。【免费下载链接】OpenNOWCustom GeForce Now Client Named OpenNOW项目地址: https://gitcode.com/gh_mirrors/op/OpenNOW创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考