Skip to main content

Working with the WebSocket Server

The SDK integrates with the Foxglove app using a WebSocket server.

For an introduction to basic logging with the WebSocket server, see the earlier example. This guide describes more of the features that the SDK and app support.

Connecting

By default, the server listens on 127.0.0.1, port 8765, which matches the app's default connection string. In the app, choose "Open connection" from the dashboard to connect to a server — see Connecting to data for details.

Here, we'll start a server in the SDK with the default options.

let server = foxglove::WebSocketServer::new()
.start_blocking()
.expect("Server failed to start");
note

The examples here use .start_blocking(), but if you're in an async context (such as a tokio.rs runtime), then you can use start().await instead.

You can change the host or port (and other options) when creating the server. If port is 0, an available port will be automatically selected.

let server = foxglove::WebSocketServer::new()
.bind("127.0.0.1", 0)
.start_blocking()
.expect("Server failed to start");

For more options, see the WebSocketServer reference

Sessions

A session describes an instance of a running WebSocket server. The server provides the connected app with a session ID, which allows the app to know whether it is connecting to a new server, or re-connecting to an existing one. You can provide a session ID explicitly when starting the server; by default, it will generate one based on the current time.

Clearing a session

During playback, you may need to reset the visualization state. For example, if you're streaming data from multiple simulation runs, you'll want to clear out data from previous runs. You can do this by clearing the running session.

server.clear_session(None);

When clearing the session, you can optionally provide a new session ID to use instead of the default time-based ID.

Status Messages

You can publish a status message to the app, which will be displayed in the Problems panel. Use this to communicate warnings and errors within the app.

server.publish_status(Status::error("Error!"));

If you provide a status ID when publishing, you can later remove the status from the Problems panel by calling remove_status.

Capabilities

You can augment the SDK's WebSocket server with additional capabilities by implementing interfaces which unlock more features in the app.

The following sections describe the additional capabilities you can build into your server.

Advertising capabilities

In some cases, as noted below, you'll have to specifically advertise these capabilities to the app so that it knows when they're available. To do this, provide one or more capabilities when constructing your server. In this example, we augment the Connecting example above to advertise Time and ClientPublish capabilities.

use foxglove::websocket::Capability;

let server = foxglove::WebSocketServer::new()
.capabilities([Capability::Time, Capability::ClientPublish])
.start_blocking();

Handling messages from the app

The Publish panel can be used send messages to the server from the app.

In addition to advertising ClientPublish support, you'll declare the encodings you support and implement at least one callback function to receive the messages.

This example uses serde_json to parse messages from the client:

cargo add serde_json
use foxglove::websocket::{Capability, Client, ClientChannel, ServerListener};

struct ExampleCallbackHandler;
impl ServerListener for ExampleCallbackHandler {
fn on_message_data(&self, client: Client, channel: &ClientChannel, message: &[u8]) {
let json: serde_json::Value =
serde_json::from_slice(message).expect("Failed to parse message");
println!(
"Client {} published to channel {}: {json}",
client.id(),
channel.id
);
}
}


let server = foxglove::WebSocketServer::new()
.capabilities([Capability::ClientPublish])
.supported_encodings(["json"])
.listener(Arc::new(ExampleCallbackHandler))
.start_blocking();

The ServerListener interface provides ways to track advertisements and subscriptions. For more detail, see the client-publish example.

Broadcasting time

You can broadcast timestamps (nanoseconds since epoch) from the server to inform many panels in the app of the server time, in cases where message timestamps disagree with wall time.

note

You must add the Time capability to your server. See advertising capabilities.

server.broadcast_time(42);