use dispatcher for room events (#30)
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
use livekit::prelude::*;
|
|
||||||
use livekit::{RoomResult, SimulateScenario};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum AsyncCmd {
|
|
||||||
RoomConnect { url: String, token: String },
|
|
||||||
RoomDisconnect,
|
|
||||||
SimulateScenario { scenario: SimulateScenario },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum UiCmd {
|
|
||||||
ConnectResult { result: RoomResult<()> },
|
|
||||||
RoomEvent { event: RoomEvent },
|
|
||||||
}
|
|
||||||
@@ -150,7 +150,7 @@ pub fn run(rt: tokio::runtime::Runtime) {
|
|||||||
|
|
||||||
async fn room_task(
|
async fn room_task(
|
||||||
_app_state: Arc<AppState>,
|
_app_state: Arc<AppState>,
|
||||||
mut room_events: RoomEvents,
|
mut room_events: mpsc::UnboundedReceiver<RoomEvent>,
|
||||||
mut close_rx: oneshot::Receiver<()>,
|
mut close_rx: oneshot::Receiver<()>,
|
||||||
ui_cmd_tx: mpsc::UnboundedSender<UiCmd>,
|
ui_cmd_tx: mpsc::UnboundedSender<UiCmd>,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ pub use crate::participant::{
|
|||||||
LocalParticipant, Participant, ParticipantEvent, ParticipantTrait, RemoteParticipant,
|
LocalParticipant, Participant, ParticipantEvent, ParticipantTrait, RemoteParticipant,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::{ConnectionState, Room, RoomError, RoomEvent, RoomEvents, RoomSession};
|
pub use crate::{ConnectionState, Room, RoomError, RoomEvent, RoomSession};
|
||||||
|
|
||||||
pub use crate::publication::{
|
pub use crate::publication::{
|
||||||
LocalTrackPublication, RemoteTrackPublication, TrackPublication, TrackPublicationTrait,
|
LocalTrackPublication, RemoteTrackPublication, TrackPublication, TrackPublicationTrait,
|
||||||
|
|||||||
+12
-6
@@ -1,5 +1,5 @@
|
|||||||
use crate::prelude::*;
|
|
||||||
use crate::participant::ConnectionQuality;
|
use crate::participant::ConnectionQuality;
|
||||||
|
use crate::prelude::*;
|
||||||
use crate::proto;
|
use crate::proto;
|
||||||
use crate::rtc_engine::EngineError;
|
use crate::rtc_engine::EngineError;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
@@ -17,8 +17,6 @@ pub mod track;
|
|||||||
|
|
||||||
pub use room_session::*;
|
pub use room_session::*;
|
||||||
|
|
||||||
pub type RoomEvents = mpsc::UnboundedReceiver<RoomEvent>;
|
|
||||||
pub type RoomEmitter = mpsc::UnboundedSender<RoomEvent>;
|
|
||||||
pub type RoomResult<T> = Result<T, RoomError>;
|
pub type RoomResult<T> = Result<T, RoomError>;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@@ -89,9 +87,12 @@ pub struct Room {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Room {
|
impl Room {
|
||||||
pub async fn connect(url: &str, token: &str) -> RoomResult<(Self, RoomEvents)> {
|
pub async fn connect(
|
||||||
let (emitter, events) = mpsc::unbounded_channel();
|
url: &str,
|
||||||
let handle = SessionHandle::connect(emitter, url, token).await?;
|
token: &str,
|
||||||
|
) -> RoomResult<(Self, mpsc::UnboundedReceiver<RoomEvent>)> {
|
||||||
|
let handle = SessionHandle::connect(url, token).await?;
|
||||||
|
let events = handle.subscribe();
|
||||||
Ok((Self { handle }, events))
|
Ok((Self { handle }, events))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +100,11 @@ impl Room {
|
|||||||
self.handle.close().await;
|
self.handle.close().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allow multiple subscribers/observers to receive events
|
||||||
|
pub fn subscribe(&self) -> mpsc::UnboundedReceiver<RoomEvent> {
|
||||||
|
self.handle.subscribe()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn session(&self) -> RoomSession {
|
pub fn session(&self) -> RoomSession {
|
||||||
self.handle.session()
|
self.handle.session()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ use crate::prelude::*;
|
|||||||
use crate::proto;
|
use crate::proto;
|
||||||
use crate::rtc_engine::{EngineEvent, EngineEvents, EngineResult, RTCEngine};
|
use crate::rtc_engine::{EngineEvent, EngineEvents, EngineResult, RTCEngine};
|
||||||
use crate::signal_client::SignalOptions;
|
use crate::signal_client::SignalOptions;
|
||||||
use crate::{RoomEmitter, RoomError, RoomEvent, RoomResult, SimulateScenario};
|
use crate::{RoomError, RoomEvent, RoomResult, SimulateScenario};
|
||||||
|
use livekit_utils::observer::Dispatcher;
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::atomic::{AtomicU8, Ordering};
|
use std::sync::atomic::{AtomicU8, Ordering};
|
||||||
@@ -43,7 +44,7 @@ struct SessionInner {
|
|||||||
active_speakers: RwLock<Vec<Participant>>,
|
active_speakers: RwLock<Vec<Participant>>,
|
||||||
rtc_engine: Arc<RTCEngine>,
|
rtc_engine: Arc<RTCEngine>,
|
||||||
local_participant: Arc<LocalParticipant>,
|
local_participant: Arc<LocalParticipant>,
|
||||||
room_emitter: RoomEmitter,
|
dispatcher: Mutex<Dispatcher<RoomEvent>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -61,7 +62,7 @@ pub struct RoomSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SessionHandle {
|
impl SessionHandle {
|
||||||
pub async fn connect(room_emitter: RoomEmitter, url: &str, token: &str) -> RoomResult<Self> {
|
pub async fn connect(url: &str, token: &str) -> RoomResult<Self> {
|
||||||
let (rtc_engine, engine_events) = RTCEngine::new();
|
let (rtc_engine, engine_events) = RTCEngine::new();
|
||||||
let rtc_engine = Arc::new(rtc_engine);
|
let rtc_engine = Arc::new(rtc_engine);
|
||||||
rtc_engine
|
rtc_engine
|
||||||
@@ -88,7 +89,7 @@ impl SessionHandle {
|
|||||||
active_speakers: Default::default(),
|
active_speakers: Default::default(),
|
||||||
rtc_engine,
|
rtc_engine,
|
||||||
local_participant,
|
local_participant,
|
||||||
room_emitter,
|
dispatcher: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
||||||
for pi in join_response.other_participants {
|
for pi in join_response.other_participants {
|
||||||
@@ -118,6 +119,10 @@ impl SessionHandle {
|
|||||||
let _ = self.session_task.await;
|
let _ = self.session_task.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn subscribe(&self) -> mpsc::UnboundedReceiver<RoomEvent> {
|
||||||
|
self.session.inner.dispatcher.lock().register()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn session(&self) -> RoomSession {
|
pub fn session(&self) -> RoomSession {
|
||||||
self.session.clone()
|
self.session.clone()
|
||||||
}
|
}
|
||||||
@@ -215,30 +220,36 @@ impl SessionInner {
|
|||||||
if let Participant::Remote(remote_participant) = participant {
|
if let Participant::Remote(remote_participant) = participant {
|
||||||
match event {
|
match event {
|
||||||
ParticipantEvent::TrackPublished { publication } => {
|
ParticipantEvent::TrackPublished { publication } => {
|
||||||
let _ = self.room_emitter.send(RoomEvent::TrackPublished {
|
self.dispatcher.lock().dispatch(&RoomEvent::TrackPublished {
|
||||||
participant: remote_participant.clone(),
|
participant: remote_participant.clone(),
|
||||||
publication,
|
publication,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ParticipantEvent::TrackUnpublished { publication } => {
|
ParticipantEvent::TrackUnpublished { publication } => {
|
||||||
let _ = self.room_emitter.send(RoomEvent::TrackUnpublished {
|
self.dispatcher
|
||||||
participant: remote_participant.clone(),
|
.lock()
|
||||||
publication,
|
.dispatch(&RoomEvent::TrackUnpublished {
|
||||||
});
|
participant: remote_participant.clone(),
|
||||||
|
publication,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
ParticipantEvent::TrackSubscribed { track, publication } => {
|
ParticipantEvent::TrackSubscribed { track, publication } => {
|
||||||
let _ = self.room_emitter.send(RoomEvent::TrackSubscribed {
|
self.dispatcher
|
||||||
participant: remote_participant.clone(),
|
.lock()
|
||||||
track,
|
.dispatch(&RoomEvent::TrackSubscribed {
|
||||||
publication,
|
participant: remote_participant.clone(),
|
||||||
});
|
track,
|
||||||
|
publication,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
ParticipantEvent::TrackUnsubscribed { track, publication } => {
|
ParticipantEvent::TrackUnsubscribed { track, publication } => {
|
||||||
let _ = self.room_emitter.send(RoomEvent::TrackUnsubscribed {
|
self.dispatcher
|
||||||
participant: remote_participant.clone(),
|
.lock()
|
||||||
track,
|
.dispatch(&RoomEvent::TrackUnsubscribed {
|
||||||
publication,
|
participant: remote_participant.clone(),
|
||||||
});
|
track,
|
||||||
|
publication,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
@@ -286,12 +297,12 @@ impl SessionInner {
|
|||||||
}
|
}
|
||||||
EngineEvent::Resuming => {
|
EngineEvent::Resuming => {
|
||||||
if self.update_connection_state(ConnectionState::Reconnecting) {
|
if self.update_connection_state(ConnectionState::Reconnecting) {
|
||||||
let _ = self.room_emitter.send(RoomEvent::Reconnecting);
|
self.dispatcher.lock().dispatch(&RoomEvent::Reconnecting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EngineEvent::Resumed => {
|
EngineEvent::Resumed => {
|
||||||
self.update_connection_state(ConnectionState::Connected);
|
self.update_connection_state(ConnectionState::Connected);
|
||||||
let _ = self.room_emitter.send(RoomEvent::Reconnected);
|
self.dispatcher.lock().dispatch(&RoomEvent::Reconnected);
|
||||||
|
|
||||||
// TODO(theomonnom): Update subscriptions settings
|
// TODO(theomonnom): Update subscriptions settings
|
||||||
// TODO(theomonnom): Send sync state
|
// TODO(theomonnom): Send sync state
|
||||||
@@ -306,7 +317,7 @@ impl SessionInner {
|
|||||||
} => {
|
} => {
|
||||||
let payload = Arc::new(payload);
|
let payload = Arc::new(payload);
|
||||||
if let Some(participant) = self.get_participant(&participant_sid.into()) {
|
if let Some(participant) = self.get_participant(&participant_sid.into()) {
|
||||||
let _ = self.room_emitter.send(RoomEvent::DataReceived {
|
self.dispatcher.lock().dispatch(&RoomEvent::DataReceived {
|
||||||
payload: payload.clone(),
|
payload: payload.clone(),
|
||||||
kind,
|
kind,
|
||||||
participant: participant.clone(),
|
participant: participant.clone(),
|
||||||
@@ -339,9 +350,9 @@ impl SessionInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.state.store(state as u8, Ordering::Release);
|
self.state.store(state as u8, Ordering::Release);
|
||||||
let _ = self
|
self.dispatcher
|
||||||
.room_emitter
|
.lock()
|
||||||
.send(RoomEvent::ConnectionStateChanged(state));
|
.dispatch(&RoomEvent::ConnectionStateChanged(state));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,8 +391,9 @@ impl SessionInner {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let _ = self
|
let _ = self
|
||||||
.room_emitter
|
.dispatcher
|
||||||
.send(RoomEvent::ParticipantConnected(remote_participant.clone()));
|
.lock()
|
||||||
|
.dispatch(&RoomEvent::ParticipantConnected(remote_participant.clone()));
|
||||||
|
|
||||||
remote_participant.update_info(pi.clone(), true);
|
remote_participant.update_info(pi.clone(), true);
|
||||||
}
|
}
|
||||||
@@ -419,8 +431,9 @@ impl SessionInner {
|
|||||||
*self.active_speakers.write() = speakers.clone();
|
*self.active_speakers.write() = speakers.clone();
|
||||||
|
|
||||||
let _ = self
|
let _ = self
|
||||||
.room_emitter
|
.dispatcher
|
||||||
.send(RoomEvent::ActiveSpeakersChanged { speakers });
|
.lock()
|
||||||
|
.dispatch(&RoomEvent::ActiveSpeakersChanged { speakers });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a connection quality update
|
/// Handle a connection quality update
|
||||||
@@ -446,10 +459,12 @@ impl SessionInner {
|
|||||||
.into();
|
.into();
|
||||||
|
|
||||||
participant.set_connection_quality(quality);
|
participant.set_connection_quality(quality);
|
||||||
let _ = self.room_emitter.send(RoomEvent::ConnectionQualityChanged {
|
self.dispatcher
|
||||||
participant,
|
.lock()
|
||||||
quality,
|
.dispatch(&RoomEvent::ConnectionQualityChanged {
|
||||||
});
|
participant,
|
||||||
|
quality,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,7 +477,7 @@ impl SessionInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.update_connection_state(ConnectionState::Reconnecting) {
|
if self.update_connection_state(ConnectionState::Reconnecting) {
|
||||||
let _ = self.room_emitter.send(RoomEvent::Reconnecting);
|
self.dispatcher.lock().dispatch(&RoomEvent::Reconnecting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,7 +487,7 @@ impl SessionInner {
|
|||||||
let join_response = self.rtc_engine.join_response().unwrap();
|
let join_response = self.rtc_engine.join_response().unwrap();
|
||||||
|
|
||||||
self.update_connection_state(ConnectionState::Connected);
|
self.update_connection_state(ConnectionState::Connected);
|
||||||
let _ = self.room_emitter.send(RoomEvent::Reconnected);
|
self.dispatcher.lock().dispatch(&RoomEvent::Reconnected);
|
||||||
|
|
||||||
if let Some(pi) = join_response.participant {
|
if let Some(pi) = join_response.participant {
|
||||||
self.local_participant.update_info(pi, true); // The sid may have changed
|
self.local_participant.update_info(pi, true); // The sid may have changed
|
||||||
@@ -490,7 +505,7 @@ impl SessionInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.update_connection_state(ConnectionState::Disconnected);
|
self.update_connection_state(ConnectionState::Disconnected);
|
||||||
let _ = self.room_emitter.send(RoomEvent::Disconnected);
|
self.dispatcher.lock().dispatch(&RoomEvent::Disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new participant
|
/// Create a new participant
|
||||||
@@ -546,9 +561,11 @@ impl SessionInner {
|
|||||||
|
|
||||||
self.participants.write().remove(&remote_participant.sid());
|
self.participants.write().remove(&remote_participant.sid());
|
||||||
|
|
||||||
let _ = self.room_emitter.send(RoomEvent::ParticipantDisconnected(
|
self.dispatcher
|
||||||
remote_participant.clone(),
|
.lock()
|
||||||
));
|
.dispatch(&RoomEvent::ParticipantDisconnected(
|
||||||
|
remote_participant.clone(),
|
||||||
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user