Rerun 多 Native Viewer 并发指南:用 gRPC 端口隔离并行可视化窗口
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
本指南基于官方 How-To 文档,讲解如何在同一台机器上同时运行多个 Rerun Native Viewer 窗口,让不同窗口展示不同的数据、或从不同视角观察同一份数据。读完你将掌握rerun --port的端口复用机制、SDK 中connect_grpc()/spawn()的定向连接方式,以及多 Viewer 场景下数据隔离与 Web Viewer 的差异。
核心机制:每个 Native Viewer 都是一个 gRPC 端口
Rerun Native Viewer(即rerun命令行程序启动的桌面 Viewer)在启动时会绑定一个本地 gRPC 端口用于接收数据流,默认端口是9876。因此,rerun的端口选择逻辑决定了你能开几个窗口:
- 若目标端口上已有Viewer 在监听:
rerun会直接连接该 Viewer(或向其发送数据),而不会再开一个新窗口; - 若目标端口上没有Viewer:
rerun才会启动一个新 Viewer 并绑定该端口。
这一"先探测、后启动"的流程,在源码 entrypoint.rs 中有清晰实现:当端口未被占用时,rerun使用指定的port作为 Viewer server 地址;当检测到同一端口已有另一个 server 运行时,它甚至会自动寻找一个空闲端口并打印提示。而在命令入口处,entrypoint.rs 将--port参数建模为PortArg枚举,同时支持"具体端口号"和auto两种取值。
正是基于"一个端口 = 一个 Viewer"的模型,要打开多个 Viewer 窗口,只需给每个窗口指定不同的--port。
命令行实战:用--port打开多个 Viewer
官方文档给出的示例完整覆盖了"复用已有窗口"与"强制新开窗口"两种典型情形:
# 启动一个 Viewer,监听默认端口 9876 $ rerun & # 这不会新建窗口 —— :9876 上已经有 Viewer 在运行了 $ rerun & # 在端口 6789 上启动第二个 Viewer $ rerun --port 6789 & # 把图片发送给第一个 Viewer(端口 9876) $ rerun image.jpg # 把图片发送给第二个 Viewer(端口 6789) $ rerun --port 6789 image.jpg从这个示例可以提炼出两条使用规则:
- 不带
--port的命令总是"打给"默认 9876 端口。无论本地是否已有 Viewer,rerun image.jpg这类数据加载命令都会把数据流导向 9876 端口上的那个 Viewer——如果该端口没有 Viewer,则会先自动启动一个; - 带
--port N的命令定向操作端口 N。既可以用它显式启动一个新的 Viewer 窗口,也可以向指定端口上已存在的 Viewer 发送数据文件。
源码层面的印证:当rerun发现目标端口已被占用时,终端会输出"Another viewer is already running, streaming data to it. Use --port auto to force a new viewer."(见 entrypoint.rs),明确提示"复用已有 Viewer"与"强制新开 Viewer"是两条互斥路径。
进阶参数:--port auto与--new
除了直接指定端口号,命令行还提供了两个自动化的端口参数,它们对多 Viewer 场景非常实用:
--port auto:仍然优先使用默认端口 9876,但如果该端口已被占用,则自动挑选一个空闲端口启动新 Viewer,避免手动寻找端口号;--new:等价于--port auto,语义是"总是新开一个 Viewer",适合在脚本里反复拉起独立窗口。
这两个参数在 entrypoint.rs 中定义为--new与--port互斥(conflicts_with = "port"),其内部端口选择逻辑同样位于 entrypoint.rs,并配有单元测试验证参数解析(如--port auto、--new、--connect与--port的组合,见 entrypoint.rs)。
命令行连接上游:--connect <url/port>
如果你不是直接给 Viewer 喂本地文件,而是希望 Viewer 作为数据接收端去订阅某个上游数据源(例如另一个 Rerun 进程或消息代理),可以用--connect:
# 连接指定端口的消息代理,Viewer 自身 server 默认开在空闲端口 $ rerun --connect 9876 # 显式同时指定上游端口与 Viewer 自身端口 $ rerun --connect 4321 --port 1234--connect接受一个 URL 或端口号:传入端口号时会被展开为rerun+http://127.0.0.1:<PORT>/proxy(展开逻辑见 entrypoint.rs)。注意--connect与--port描述的是两个不同的端口——前者是上游消息代理的端口,后者是Viewer 本地 server的端口,二者相互独立(测试connect_and_viewer_server_ports_are_independent专门验证了这一点,见 entrypoint.rs)。
从 SDK 定向连接:connect_grpc()
当你从 Python SDK 发送数据时,rr.connect_grpc()决定数据流向哪个 Viewer。官方示例:
import rerun as rr # 连接默认端口(9876)上的 Viewer rr.init("rerun_example_demo") rr.connect_grpc() # 或者显式连接指定端口的 Viewer rr.connect_grpc("rerun+http://127.0.0.1:6789")在 SDK 实现中,connect_grpc()的 URL 参数遵循严格的格式约束(见 sinks.py):
- scheme 必须是
rerun://、rerun+http://或rerun+https://三者之一; - pathname 必须是
/proxy; - 不传参数时,默认目标是
rerun+http://127.0.0.1:9876/proxy。
也就是说,上面示例中的rerun+http://127.0.0.1:6789实际等价于rerun+http://127.0.0.1:6789/proxy。多 Viewer 场景下的典型用法是:在程序里维护多个 Recording,分别connect_grpc()到不同的端口 URL,即可把数据分发给不同的 Viewer 窗口。
提示:
connect_grpc()在调用rr.init()之后、开始log数据之前调用才会生效;若未先init,SDK 会抛出 "You must call rerun.init before connecting to a viewer" 的异常(见 sinks.py)。
自动拉起 Viewer:spawn()
如果你希望"开一个能收数据的 Viewer,没有就自动起一个",spawn()是更省事的选择。它由 SDK 直接启动rerun进程,其完整签名与参数(见 recording_stream.py)如下:
rr.init("rerun_example_demo") rr.spawn( port=9876, # 要监听 / 连接的端口 connect=True, # 启动后是否自动连接并开始流式传输数据 memory_limit="75%", # Viewer 内存上限,如 "16GB" 或 "50%" hide_welcome_screen=False, detach_process=True, # 将 Viewer 进程与应用进程分离 )与多个rerun &命令的行为一致,spawn()默认也是"复用优先":若 9876 端口已有 Viewer 在运行,它会直接复用该 Viewer 并开始发送数据,而不会新开窗口;只有当你传入其他port时,才会定向到对应的 Viewer。因此,在"同一个 SDK 程序控制多个 Viewer"的场景中,可以多次调用spawn(port=...)指向不同端口。
数据隔离:每个 Viewer 拥有独立的 Chunk Store
每个 Viewer 各自维护一个独立的 Chunk Store,因此发送到不同 Viewer 的数据彼此完全隔离:同一个实体路径(Entity Path)、同一个时间序列,可以在两个窗口里以不同的状态存在,互不影响。这也意味着多 Viewer 方案的适用场景包括:
- 同时对比两份不同的数据集(例如不同传感器、不同录制片段);
- 用不同窗口展示同一份数据的多种视图/Blueprint 布局;
- 并行调试多个长时间运行的日志流,互不阻塞。
需要注意:Web Viewer 不走 gRPC 端口
以上端口机制仅适用于Native Viewer。Web Viewer(通过rerun --web-viewer或浏览器端加载的方式使用)的通信路径不同——它通过WebSocket与本地服务通信,而不是像 Native Viewer 那样直接绑定 gRPC 端口。因此,本文的--port多开方案不能直接套用到 Web Viewer 场景;Web Viewer 相关端口由--web-viewer-port等参数单独控制(见 entrypoint.rs,其中0表示随机挑选端口)。
小结:多 Viewer 速查表
| 目标 | 命令 / API |
|---|---|
| 默认端口启动 / 复用 Viewer | rerun &或rr.spawn() |
| 在指定端口强制新开 Viewer | rerun --port 6789 & |
| 自动避开被占用端口 | rerun --port auto &或rerun --new & |
| 向指定端口发送本地文件 | rerun --port 6789 image.jpg |
| SDK 定向连接指定 Viewer | rr.connect_grpc("rerun+http://127.0.0.1:6789") |
一句话总结:Native Viewer 与 gRPC 端口一一对应,--port即窗口的"身份证";对默认 9876 端口的操作总是复用既有窗口,显式指定不同端口即可并行开多个彼此数据隔离的 Viewer。
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考