Skip to content

Commit 775191b

Browse files
Merge branch 'main' into feature/unified_method_style
2 parents e18061e + c8a2508 commit 775191b

9 files changed

Lines changed: 1008 additions & 29 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ lib/
3434
web/
3535
*trace.json
3636
compile_commands.json
37+
user_stories

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This is **client-sdk-cpp**, the official LiveKit C++ client SDK. It wraps a Rust
88

99
### Core Principle
1010
Rust owns as much of the business logic as possible. The C++ layer should be a thin wrapper around the Rust core. If a feature may be used by another SDK it should be implemented in Rust. Since this is an SDK,
11-
ensure backwards compatibility is maintained when possible.
11+
ensure backwards compatibility is maintained when possible. Do not update auto-generated code.
1212

1313
### Platform Support
1414
The SDK must be supported on the following platforms:

client-sdk-rust

src/ffi_client.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
namespace livekit {
3636

3737
namespace {
38-
3938
inline void logAndThrow(const std::string& error_msg) {
4039
LK_LOG_ERROR("LiveKit SDK Error: {}", error_msg);
4140
throw std::runtime_error(error_msg);

src/room.cpp

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,11 @@
1818

1919
#include <functional>
2020

21-
#include "data_track.pb.h"
2221
#include "ffi.pb.h"
2322
#include "ffi_client.h"
2423
#include "livekit/audio_stream.h"
2524
#include "livekit/e2ee.h"
26-
#include "livekit/livekit.h"
27-
#include "livekit/local_data_track.h"
2825
#include "livekit/local_participant.h"
29-
#include "livekit/local_track_publication.h"
3026
#include "livekit/remote_audio_track.h"
3127
#include "livekit/remote_data_track.h"
3228
#include "livekit/remote_participant.h"
@@ -66,6 +62,16 @@ std::shared_ptr<livekit::RemoteParticipant> createRemoteParticipant(const proto:
6662
pinfo.metadata(), std::move(attrs), kind, reason);
6763
}
6864

65+
void readyForRoomEvent(std::uint64_t room_handle) {
66+
FfiRequest req;
67+
req.mutable_ready_for_room_event()->set_room_handle(room_handle);
68+
69+
const auto resp = FfiClient::instance().sendRequest(req);
70+
if (!resp.has_ready_for_room_event()) {
71+
throw std::runtime_error("FfiResponse missing ready_for_room_event");
72+
}
73+
}
74+
6975
} // namespace
7076
Room::Room() : subscription_thread_dispatcher_(std::make_unique<SubscriptionThreadDispatcher>()) {}
7177

@@ -118,12 +124,21 @@ bool Room::connect(const std::string& url, const std::string& token, const RoomO
118124
}
119125
connection_state_ = ConnectionState::Reconnecting;
120126
}
121-
auto fut = FfiClient::instance().connectAsync(url, token, options);
127+
128+
FfiClient::ListenerId listenerId = 0;
122129
try {
130+
listenerId = FfiClient::instance().addListener([this](const proto::FfiEvent& e) { OnEvent(e); });
131+
{
132+
const std::scoped_lock<std::mutex> g(lock_);
133+
listener_id_ = listenerId;
134+
}
135+
136+
auto fut = FfiClient::instance().connectAsync(url, token, options);
123137
auto connectCb = fut.get(); // fut will throw if it fails to connect to the room
124138

125139
const auto& owned_room = connectCb.result().room();
126140
auto new_room_handle = std::make_shared<FfiHandle>(owned_room.handle().id());
141+
const auto room_handle_id = static_cast<std::uint64_t>(new_room_handle->get());
127142
auto new_room_info = fromProto(owned_room.info());
128143

129144
// Setup local particpant
@@ -147,6 +162,7 @@ bool Room::connect(const std::string& url, const std::string& token, const RoomO
147162
std::make_unique<LocalParticipant>(std::move(participant_handle), pinfo.sid(), pinfo.name(), pinfo.identity(),
148163
pinfo.metadata(), std::move(attrs), kind, reason);
149164
}
165+
150166
// Setup remote participants
151167
std::unordered_map<std::string, std::shared_ptr<RemoteParticipant>> new_remote_participants;
152168
{
@@ -184,18 +200,32 @@ bool Room::connect(const std::string& url, const std::string& token, const RoomO
184200
connection_state_ = ConnectionState::Connected;
185201
}
186202

187-
// Install listener (Room is fully initialized)
188-
auto listenerId = FfiClient::instance().addListener([this](const proto::FfiEvent& e) { onEvent(e); });
203+
readyForRoomEvent(room_handle_id);
204+
return true;
205+
} catch (const std::exception& e) {
206+
int listener_to_remove = 0;
207+
std::unique_ptr<LocalParticipant> local_participant_to_cleanup;
189208
{
190209
const std::scoped_lock<std::mutex> g(lock_);
191-
listener_id_ = listenerId;
210+
connection_state_ = ConnectionState::Disconnected;
211+
if (listener_id_ == listenerId) {
212+
listener_to_remove = listener_id_;
213+
listener_id_ = 0;
214+
}
215+
local_participant_to_cleanup = std::move(local_participant_);
216+
remote_participants_.clear();
217+
room_handle_.reset();
218+
e2ee_manager_.reset();
219+
text_stream_readers_.clear();
220+
byte_stream_readers_.clear();
192221
}
193-
194-
return true;
195-
} catch (const std::exception& e) {
196-
// On error, set the connection_state_ to Disconnected
197-
connection_state_ = ConnectionState::Disconnected;
198-
LK_LOG_ERROR("Room::connect failed: {}", e.what());
222+
if (local_participant_to_cleanup) {
223+
local_participant_to_cleanup->shutdown();
224+
}
225+
if (listener_to_remove != 0) {
226+
FfiClient::instance().removeListener(listener_to_remove);
227+
}
228+
LK_LOG_ERROR("Room::Connect failed: {}", e.what());
199229
return false;
200230
}
201231
}

0 commit comments

Comments
 (0)