@@ -887,6 +887,7 @@ fn run_impl(
887
887
) -> anyhow:: Result < ( ) > {
888
888
#[ cfg( feature = "native_viewer" ) ]
889
889
let profiler = profiler ( & args) ;
890
+ let mut is_another_viewer_running = false ;
890
891
891
892
#[ cfg( feature = "native_viewer" ) ]
892
893
let startup_options = {
@@ -951,13 +952,26 @@ fn run_impl(
951
952
952
953
#[ cfg( feature = "server" ) ]
953
954
{
954
- let server_options = re_sdk_comms:: ServerOptions {
955
- max_latency_sec : parse_max_latency ( args. drop_at_latency . as_ref ( ) ) ,
956
- quiet : false ,
957
- } ;
958
- let tcp_listener: Receiver < LogMsg > =
959
- re_sdk_comms:: serve ( & args. bind , args. port , server_options) ?;
960
- rxs. push ( tcp_listener) ;
955
+ // Check if there is already a viewer running
956
+ // and if so, send the data to it.
957
+ use std:: net:: TcpStream ;
958
+ let connect_addr = std:: net:: SocketAddr :: new ( args. bind . parse ( ) . unwrap ( ) , args. port ) ;
959
+ if TcpStream :: connect_timeout ( & connect_addr, std:: time:: Duration :: from_secs ( 1 ) ) . is_ok ( )
960
+ {
961
+ re_log:: info!(
962
+ addr = %connect_addr,
963
+ "A process is already listening at this address. Assuming it's a Rerun Viewer."
964
+ ) ;
965
+ is_another_viewer_running = true ;
966
+ } else {
967
+ let server_options = re_sdk_comms:: ServerOptions {
968
+ max_latency_sec : parse_max_latency ( args. drop_at_latency . as_ref ( ) ) ,
969
+ quiet : false ,
970
+ } ;
971
+ let tcp_listener: Receiver < LogMsg > =
972
+ re_sdk_comms:: serve ( & args. bind , args. port , server_options) ?;
973
+ rxs. push ( tcp_listener) ;
974
+ }
961
975
}
962
976
963
977
rxs
@@ -1030,6 +1044,22 @@ fn run_impl(
1030
1044
1031
1045
return Ok ( ( ) ) ;
1032
1046
}
1047
+ } else if is_another_viewer_running {
1048
+ re_log:: info!( "Another viewer is already running, streaming data to it." ) ;
1049
+ // get current active recording
1050
+ use re_sdk:: RecordingStream ;
1051
+ let static_ = true ;
1052
+
1053
+ let Some ( active_recording) = RecordingStream :: get ( re_sdk:: StoreKind :: Recording , None )
1054
+ else {
1055
+ anyhow:: bail!( "No active recording found!" ) ;
1056
+ } ;
1057
+ // map is lazy, so we need take the result by let _ = ...
1058
+ let _ = args
1059
+ . url_or_paths
1060
+ . iter ( )
1061
+ . map ( |path| active_recording. log_file_from_path ( path, None , static_) ) ;
1062
+ Ok ( ( ) )
1033
1063
} else {
1034
1064
#[ cfg( feature = "native_viewer" ) ]
1035
1065
return re_viewer:: run_native_app (
0 commit comments