Skip to content

Commit cb5f648

Browse files
ReadyForRoomEvent and new tests
1 parent 82ee340 commit cb5f648

11 files changed

Lines changed: 1002 additions & 28 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

include/livekit/rpc_error.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class LIVEKIT_API RpcError : public std::runtime_error {
7777
* @param data Optional extra data, e.g. JSON. Empty string means no data.
7878
*/
7979
RpcError(ErrorCode code, std::string message, std::string data = {});
80+
~RpcError() override;
8081

8182
/**
8283
* Numeric error code.

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: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +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/local_data_track.h"
2725
#include "livekit/local_participant.h"
28-
#include "livekit/local_track_publication.h"
2926
#include "livekit/remote_audio_track.h"
3027
#include "livekit/remote_data_track.h"
3128
#include "livekit/remote_participant.h"
@@ -65,6 +62,16 @@ std::shared_ptr<livekit::RemoteParticipant> createRemoteParticipant(const proto:
6562
pinfo.metadata(), std::move(attrs), kind, reason);
6663
}
6764

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+
6875
} // namespace
6976
Room::Room() : subscription_thread_dispatcher_(std::make_unique<SubscriptionThreadDispatcher>()) {}
7077

@@ -104,20 +111,28 @@ void Room::setDelegate(RoomDelegate* delegate) {
104111

105112
bool Room::Connect(const std::string& url, const std::string& token, const RoomOptions& options) {
106113
TRACE_EVENT0("livekit", "Room::Connect");
107-
108114
{
109115
const std::scoped_lock<std::mutex> g(lock_);
110116
if (connection_state_ != ConnectionState::Disconnected) {
111117
throw std::runtime_error("already connected");
112118
}
113119
connection_state_ = ConnectionState::Reconnecting;
114120
}
115-
auto fut = FfiClient::instance().connectAsync(url, token, options);
121+
122+
FfiClient::ListenerId listenerId = 0;
116123
try {
124+
listenerId = FfiClient::instance().AddListener([this](const proto::FfiEvent& e) { OnEvent(e); });
125+
{
126+
const std::scoped_lock<std::mutex> g(lock_);
127+
listener_id_ = listenerId;
128+
}
129+
130+
auto fut = FfiClient::instance().connectAsync(url, token, options);
117131
auto connectCb = fut.get(); // fut will throw if it fails to connect to the room
118132

119133
const auto& owned_room = connectCb.result().room();
120134
auto new_room_handle = std::make_shared<FfiHandle>(owned_room.handle().id());
135+
const auto room_handle_id = static_cast<std::uint64_t>(new_room_handle->get());
121136
auto new_room_info = fromProto(owned_room.info());
122137

123138
// Setup local particpant
@@ -141,6 +156,7 @@ bool Room::Connect(const std::string& url, const std::string& token, const RoomO
141156
std::make_unique<LocalParticipant>(std::move(participant_handle), pinfo.sid(), pinfo.name(), pinfo.identity(),
142157
pinfo.metadata(), std::move(attrs), kind, reason);
143158
}
159+
144160
// Setup remote participants
145161
std::unordered_map<std::string, std::shared_ptr<RemoteParticipant>> new_remote_participants;
146162
{
@@ -178,17 +194,31 @@ bool Room::Connect(const std::string& url, const std::string& token, const RoomO
178194
connection_state_ = ConnectionState::Connected;
179195
}
180196

181-
// Install listener (Room is fully initialized)
182-
auto listenerId = FfiClient::instance().AddListener([this](const proto::FfiEvent& e) { OnEvent(e); });
197+
readyForRoomEvent(room_handle_id);
198+
return true;
199+
} catch (const std::exception& e) {
200+
int listener_to_remove = 0;
201+
std::unique_ptr<LocalParticipant> local_participant_to_cleanup;
183202
{
184203
const std::scoped_lock<std::mutex> g(lock_);
185-
listener_id_ = listenerId;
204+
connection_state_ = ConnectionState::Disconnected;
205+
if (listener_id_ == listenerId) {
206+
listener_to_remove = listener_id_;
207+
listener_id_ = 0;
208+
}
209+
local_participant_to_cleanup = std::move(local_participant_);
210+
remote_participants_.clear();
211+
room_handle_.reset();
212+
e2ee_manager_.reset();
213+
text_stream_readers_.clear();
214+
byte_stream_readers_.clear();
215+
}
216+
if (local_participant_to_cleanup) {
217+
local_participant_to_cleanup->shutdown();
218+
}
219+
if (listener_to_remove != 0) {
220+
FfiClient::instance().RemoveListener(listener_to_remove);
186221
}
187-
188-
return true;
189-
} catch (const std::exception& e) {
190-
// On error, set the connection_state_ to Disconnected
191-
connection_state_ = ConnectionState::Disconnected;
192222
LK_LOG_ERROR("Room::Connect failed: {}", e.what());
193223
return false;
194224
}

src/rpc_error.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ RpcError::RpcError(std::uint32_t code, std::string message, std::string data)
2626
RpcError::RpcError(ErrorCode code, std::string message, std::string data)
2727
: RpcError(static_cast<std::uint32_t>(code), std::move(message), std::move(data)) {}
2828

29+
RpcError::~RpcError() = default;
30+
2931
std::uint32_t RpcError::code() const noexcept { return code_; }
3032

3133
const std::string& RpcError::message() const noexcept { return message_; }

0 commit comments

Comments
 (0)