Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 43 additions & 5 deletions docs/integration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ SendspinClient client(std::move(config));

## Step 2: Add Roles

Add only the roles your application needs. All roles must be added before calling `start_server()`.
Add only the roles your application needs. All roles must be added before the first call to `start()`.

### Player Role (Audio Playback)

Expand Down Expand Up @@ -494,6 +494,12 @@ struct MyClientListener : SendspinClientListener {
void on_release_high_performance() override {
esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
}

// Called when a request_stop() teardown completes (see Clean shutdown below). Everything
// is torn down at this point; it is safe to call start() again or destroy the client.
void on_stopped() override {
mark_client_stopped();
}
};
```

Expand Down Expand Up @@ -522,7 +528,7 @@ client.set_persistence_provider(&persistence_provider); // Optional
```cpp
// Start the WebSocket server and sync task.
// Task priorities and PSRAM settings are taken from SendspinClientConfig.
if (!client.start_server()) {
if (!client.start()) {
// Handle failure
return 1;
}
Expand All @@ -537,8 +543,28 @@ while (running) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

// Clean shutdown
client.disconnect(SendspinGoodbyeReason::SHUTDOWN);
// Clean shutdown: sends a goodbye, closes every connection, and stops the WebSocket
// server and background threads. Call start() again later to restart the whole stack;
// disconnect(SendspinGoodbyeReason) is still available to drop just the active
// connection while leaving the server listening.
client.stop();
```

If blocking the main loop during shutdown is a concern (for example inside a firmware main
loop), use `request_stop()` instead: it returns immediately, and the teardown completes over
subsequent `loop()` calls once every connection has closed and the background threads have wound
down. A fixed grace deadline caps how long that wait runs before the teardown is forced, but not
the forced teardown itself: the `loop()` tick that reaches the deadline joins the role threads,
and a listener callback still running holds that join until it returns. Completion is reported
through `SendspinClientListener::on_stopped()` and can be polled via `get_run_state()`:

```cpp
client.request_stop();

while (client.get_run_state() != SendspinRunState::STOPPED) {
client.loop(); // on_stopped() fires from here when the teardown finishes
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
```

## Sending Commands
Expand Down Expand Up @@ -700,7 +726,7 @@ int main() {
player.set_listener(&player_listener);
client.set_network_provider(&network);

client.start_server();
client.start();

while (true) {
client.loop();
Expand Down Expand Up @@ -917,6 +943,18 @@ These represent commands the server can send to the player. The player advertise
| `ERROR` | Error state |
| `EXTERNAL_SOURCE` | Playing from an external source |

### SendspinRunState

| Value | Description |
|---|---|
| `STOPPED` | Before the first `start()` and after a stop completes |
| `RUNNING` | After a successful `start()` |
| `STOPPING` | During either teardown path, until it completes |

Returned by `client.get_run_state()`; `is_started()` is equivalent to `RUNNING`. `STOPPING` covers
both the window between `request_stop()` and its completion and the duration of a synchronous
`stop()` call, so a callback invoked during a teardown observes `STOPPING`, not `STOPPED`.

### SendspinGoodbyeReason

| Value | Description |
Expand Down
74 changes: 52 additions & 22 deletions docs/internals.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examples/basic_client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ int main(int argc, char* argv[]) {
// Start the server
fprintf(stderr, "Starting Sendspin basic client on port %u...\n", server_port);

if (!client.start_server()) {
if (!client.start()) {
fprintf(stderr, "Failed to start server\n");
return 1;
}
Expand Down Expand Up @@ -373,7 +373,7 @@ int main(int argc, char* argv[]) {
#ifdef SENDSPIN_HAS_MDNS
mdns.stop();
#endif
client.disconnect(SendspinGoodbyeReason::SHUTDOWN);
client.stop();

#ifndef SENDSPIN_HAS_PORTAUDIO
fprintf(stderr, "Total audio bytes received: %zu\n", null_audio_total_bytes);
Expand Down
4 changes: 2 additions & 2 deletions examples/tui_client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ int main(int argc, char* argv[]) {
#endif

// Start the server
if (!client.start_server()) {
if (!client.start()) {
fprintf(stderr, "Failed to start server\n");
return 1;
}
Expand Down Expand Up @@ -951,7 +951,7 @@ int main(int argc, char* argv[]) {
mdns_browser.stop();
mdns.stop();
#endif
client.disconnect(SendspinGoodbyeReason::SHUTDOWN);
client.stop();

return 0;
}
Loading
Loading