@@ -4,7 +4,7 @@ use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
44
55use clap:: Parser ;
66use dimos_viewer:: interaction:: { LcmPublisher , KeyboardHandler , click_event_from_ms} ;
7- use rerun:: external:: { eframe, egui, re_crash_handler, re_grpc_server, re_log, re_memory, re_viewer} ;
7+ use rerun:: external:: { eframe, egui, re_crash_handler, re_grpc_client , re_grpc_server, re_log, re_memory, re_uri , re_viewer} ;
88
99#[ global_allocator]
1010static GLOBAL : re_memory:: AccountingAllocator < mimalloc:: MiMalloc > =
@@ -48,6 +48,16 @@ struct Args {
4848 /// Hint that data will arrive shortly (suppresses "waiting for data" message).
4949 #[ arg( long) ]
5050 expect_data_soon : bool ,
51+
52+ /// Do not start a local gRPC server; instead connect to an existing one.
53+ ///
54+ /// Optionally accepts a URL to a gRPC proxy server.
55+ /// The scheme must be one of `rerun://`, `rerun+http://`, or `rerun+https://`,
56+ /// and the pathname must be `/proxy`.
57+ ///
58+ /// Defaults to `rerun+http://127.0.0.1:<port>/proxy`.
59+ #[ arg( long) ]
60+ connect : Option < Option < String > > ,
5161}
5262
5363/// Wraps re_viewer::App to add keyboard control interception.
@@ -110,19 +120,27 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
110120 re_log:: setup_logging ( ) ;
111121 re_crash_handler:: install_crash_handlers ( re_viewer:: build_info ( ) ) ;
112122
113- // Listen for gRPC connections from Rerun's logging SDKs.
114- let listen_addr = format ! ( "0.0.0.0:{}" , args. port) ;
115- re_log:: info!( "Listening for SDK connections on {listen_addr}" ) ;
116- let server_memory_limit = re_memory:: MemoryLimit :: parse ( & args. server_memory_limit )
117- . expect ( "Bad --server-memory-limit" ) ;
118- let rx_log = re_grpc_server:: spawn_with_recv (
119- listen_addr. parse ( ) ?,
120- re_grpc_server:: ServerOptions {
121- memory_limit : server_memory_limit,
122- ..Default :: default ( )
123- } ,
124- re_grpc_server:: shutdown:: never ( ) ,
125- ) ;
123+ // Either connect to an existing gRPC proxy, or spawn a local server.
124+ let rx_log = if let Some ( url) = args. connect . clone ( ) {
125+ let url = url. unwrap_or_else ( || format ! ( "rerun+http://127.0.0.1:{}/proxy" , args. port) ) ;
126+ let proxy_uri: re_uri:: ProxyUri = url. parse ( )
127+ . expect ( "Bad --connect URL: expected format rerun+http://host:port/proxy" ) ;
128+ re_log:: info!( "Connecting to existing gRPC proxy at {proxy_uri}" ) ;
129+ re_grpc_client:: stream ( proxy_uri)
130+ } else {
131+ let listen_addr = format ! ( "0.0.0.0:{}" , args. port) ;
132+ re_log:: info!( "Listening for SDK connections on {listen_addr}" ) ;
133+ let server_memory_limit = re_memory:: MemoryLimit :: parse ( & args. server_memory_limit )
134+ . expect ( "Bad --server-memory-limit" ) ;
135+ re_grpc_server:: spawn_with_recv (
136+ listen_addr. parse ( ) ?,
137+ re_grpc_server:: ServerOptions {
138+ memory_limit : server_memory_limit,
139+ ..Default :: default ( )
140+ } ,
141+ re_grpc_server:: shutdown:: never ( ) ,
142+ )
143+ } ;
126144
127145 // Create LCM publisher for click events
128146 let lcm_publisher = LcmPublisher :: new ( LCM_CHANNEL . to_string ( ) )
0 commit comments