1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::sync::{Arc, Weak};
use livekit::id::ParticipantIdentity;
use crate::remote_access::participant::Participant;
use crate::remote_common::ClientId;
use crate::remote_common::fetch_asset::SendAssetResponse;
/// Represents a connected remote access client.
#[derive(Debug, Clone)]
pub struct Client {
/// Locally-significant identifier for this particular instance of this participant.
client_id: ClientId,
/// LiveKit participant ID.
participant_id: ParticipantIdentity,
/// Weak reference to the participant, used for sending asset responses.
/// Only set when created via `with_sender`. Using Weak allows the participant
/// to be cleaned up even if a slow handler is still holding a Client reference.
participant: Option<Weak<Participant>>,
}
impl Client {
/// Instantiate a new client.
pub(super) fn new(client_id: ClientId, participant_id: ParticipantIdentity) -> Self {
Self {
client_id,
participant_id,
participant: None,
}
}
/// Instantiate a new client with the ability to send asset responses.
pub(super) fn with_sender(
client_id: ClientId,
participant_id: ParticipantIdentity,
participant: &Arc<Participant>,
) -> Self {
Self {
client_id,
participant_id,
participant: Some(Arc::downgrade(participant)),
}
}
/// Returns the locally-significant client ID.
pub fn id(&self) -> ClientId {
self.client_id
}
/// Returns the client-provided identity.
///
/// This is public for testing purposes, but not intended for end-users.
#[doc(hidden)]
pub fn participant_id(&self) -> &str {
&self.participant_id.0
}
}
impl SendAssetResponse for Client {
/// Send a fetch asset response to the client.
/// Does nothing if the client has no sender or if the participant has been dropped.
fn send_asset_response(&self, result: Result<&[u8], &str>, request_id: u32) {
let Some(weak) = &self.participant else {
tracing::debug!(
client_id = ?self.client_id,
participant_id = ?self.participant_id,
request_id,
"send_asset_response called but participant is not set"
);
return;
};
let Some(participant) = weak.upgrade() else {
tracing::debug!(
client_id = ?self.client_id,
participant_id = ?self.participant_id,
request_id,
"participant disconnected, dropping asset response"
);
return;
};
match result {
Ok(data) => participant.send_asset_response(data, request_id),
Err(err) => participant.send_asset_error(err, request_id),
}
}
}