mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 18:33:09 +00:00
Remove participants from live-kit rooms when they leave zed rooms
This commit is contained in:
parent
c9225bb87c
commit
cce00526b9
4 changed files with 71 additions and 29 deletions
|
@ -2,6 +2,9 @@ DATABASE_URL = "postgres://postgres@localhost/zed"
|
|||
HTTP_PORT = 8080
|
||||
API_TOKEN = "secret"
|
||||
INVITE_LINK_PREFIX = "http://localhost:3000/invites/"
|
||||
LIVE_KIT_SERVER = "http://localhost:7880"
|
||||
LIVE_KIT_KEY = "devkey"
|
||||
LIVE_KIT_SECRET = "secret"
|
||||
|
||||
# HONEYCOMB_API_KEY=
|
||||
# HONEYCOMB_DATASET=
|
||||
|
|
|
@ -473,6 +473,7 @@ impl Server {
|
|||
|
||||
let mut projects_to_unshare = Vec::new();
|
||||
let mut contacts_to_update = HashSet::default();
|
||||
let mut room_left = None;
|
||||
{
|
||||
let mut store = self.store().await;
|
||||
let removed_connection = store.remove_connection(connection_id)?;
|
||||
|
@ -501,23 +502,24 @@ impl Server {
|
|||
});
|
||||
}
|
||||
|
||||
if let Some(room) = removed_connection.room {
|
||||
self.room_updated(&room);
|
||||
room_left = Some(self.room_left(&room, removed_connection.user_id));
|
||||
}
|
||||
|
||||
contacts_to_update.insert(removed_connection.user_id);
|
||||
for connection_id in removed_connection.canceled_call_connection_ids {
|
||||
self.peer
|
||||
.send(connection_id, proto::CallCanceled {})
|
||||
.trace_err();
|
||||
contacts_to_update.extend(store.user_id_for_connection(connection_id).ok());
|
||||
}
|
||||
|
||||
if let Some(room) = removed_connection
|
||||
.room_id
|
||||
.and_then(|room_id| store.room(room_id))
|
||||
{
|
||||
self.room_updated(room);
|
||||
}
|
||||
|
||||
contacts_to_update.insert(removed_connection.user_id);
|
||||
};
|
||||
|
||||
if let Some(room_left) = room_left {
|
||||
room_left.await.trace_err();
|
||||
}
|
||||
|
||||
for user_id in contacts_to_update {
|
||||
self.update_user_contacts(user_id).await.trace_err();
|
||||
}
|
||||
|
@ -682,6 +684,7 @@ impl Server {
|
|||
|
||||
async fn leave_room(self: Arc<Server>, message: TypedEnvelope<proto::LeaveRoom>) -> Result<()> {
|
||||
let mut contacts_to_update = HashSet::default();
|
||||
let room_left;
|
||||
{
|
||||
let mut store = self.store().await;
|
||||
let user_id = store.user_id_for_connection(message.sender_id)?;
|
||||
|
@ -720,9 +723,8 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(room) = left_room.room {
|
||||
self.room_updated(room);
|
||||
}
|
||||
self.room_updated(&left_room.room);
|
||||
room_left = self.room_left(&left_room.room, user_id);
|
||||
|
||||
for connection_id in left_room.canceled_call_connection_ids {
|
||||
self.peer
|
||||
|
@ -732,6 +734,7 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
room_left.await.trace_err();
|
||||
for user_id in contacts_to_update {
|
||||
self.update_user_contacts(user_id).await?;
|
||||
}
|
||||
|
@ -880,6 +883,20 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
fn room_left(&self, room: &proto::Room, user_id: UserId) -> impl Future<Output = Result<()>> {
|
||||
let client = self.app_state.live_kit_client.clone();
|
||||
let room_name = room.live_kit_room.clone();
|
||||
async move {
|
||||
if let Some(client) = client {
|
||||
client
|
||||
.remove_participant(room_name, user_id.to_string())
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn share_project(
|
||||
self: Arc<Server>,
|
||||
request: TypedEnvelope<proto::ShareProject>,
|
||||
|
|
|
@ -4,7 +4,7 @@ use collections::{btree_map, BTreeMap, BTreeSet, HashMap, HashSet};
|
|||
use nanoid::nanoid;
|
||||
use rpc::{proto, ConnectionId};
|
||||
use serde::Serialize;
|
||||
use std::{mem, path::PathBuf, str, time::Duration};
|
||||
use std::{borrow::Cow, mem, path::PathBuf, str, time::Duration};
|
||||
use time::OffsetDateTime;
|
||||
use tracing::instrument;
|
||||
use util::post_inc;
|
||||
|
@ -85,12 +85,12 @@ pub struct Channel {
|
|||
pub type ReplicaId = u16;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RemovedConnectionState {
|
||||
pub struct RemovedConnectionState<'a> {
|
||||
pub user_id: UserId,
|
||||
pub hosted_projects: Vec<Project>,
|
||||
pub guest_projects: Vec<LeftProject>,
|
||||
pub contact_ids: HashSet<UserId>,
|
||||
pub room_id: Option<RoomId>,
|
||||
pub room: Option<Cow<'a, proto::Room>>,
|
||||
pub canceled_call_connection_ids: Vec<ConnectionId>,
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ pub struct LeftProject {
|
|||
}
|
||||
|
||||
pub struct LeftRoom<'a> {
|
||||
pub room: Option<&'a proto::Room>,
|
||||
pub room: Cow<'a, proto::Room>,
|
||||
pub unshared_projects: Vec<Project>,
|
||||
pub left_projects: Vec<LeftProject>,
|
||||
pub canceled_call_connection_ids: Vec<ConnectionId>,
|
||||
|
@ -218,7 +218,7 @@ impl Store {
|
|||
let left_room = self.leave_room(room_id, connection_id)?;
|
||||
result.hosted_projects = left_room.unshared_projects;
|
||||
result.guest_projects = left_room.left_projects;
|
||||
result.room_id = Some(room_id);
|
||||
result.room = Some(Cow::Owned(left_room.room.into_owned()));
|
||||
result.canceled_call_connection_ids = left_room.canceled_call_connection_ids;
|
||||
}
|
||||
|
||||
|
@ -495,12 +495,14 @@ impl Store {
|
|||
}
|
||||
});
|
||||
|
||||
if room.participants.is_empty() && room.pending_participant_user_ids.is_empty() {
|
||||
self.rooms.remove(&room_id);
|
||||
}
|
||||
let room = if room.participants.is_empty() && room.pending_participant_user_ids.is_empty() {
|
||||
Cow::Owned(self.rooms.remove(&room_id).unwrap())
|
||||
} else {
|
||||
Cow::Borrowed(self.rooms.get(&room_id).unwrap())
|
||||
};
|
||||
|
||||
Ok(LeftRoom {
|
||||
room: self.rooms.get(&room_id),
|
||||
room,
|
||||
unshared_projects,
|
||||
left_projects,
|
||||
canceled_call_connection_ids,
|
||||
|
|
|
@ -2,13 +2,14 @@ use crate::{proto, token};
|
|||
use anyhow::{anyhow, Result};
|
||||
use prost::Message;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
use std::future::Future;
|
||||
use std::{future::Future, sync::Arc};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Client {
|
||||
http: reqwest::Client,
|
||||
uri: String,
|
||||
key: String,
|
||||
secret: String,
|
||||
uri: Arc<str>,
|
||||
key: Arc<str>,
|
||||
secret: Arc<str>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
|
@ -19,9 +20,9 @@ impl Client {
|
|||
|
||||
Self {
|
||||
http: reqwest::Client::new(),
|
||||
uri,
|
||||
key,
|
||||
secret,
|
||||
uri: uri.into(),
|
||||
key: key.into(),
|
||||
secret: secret.into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +50,26 @@ impl Client {
|
|||
proto::DeleteRoomRequest { room: name },
|
||||
);
|
||||
async move {
|
||||
response.await?;
|
||||
let _: proto::DeleteRoomResponse = response.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_participant(
|
||||
&self,
|
||||
room: String,
|
||||
identity: String,
|
||||
) -> impl Future<Output = Result<()>> {
|
||||
let response = self.request(
|
||||
"twirp/livekit.RoomService/RemoveParticipant",
|
||||
token::VideoGrant {
|
||||
room_admin: Some(true),
|
||||
..Default::default()
|
||||
},
|
||||
proto::RoomParticipantIdentity { room, identity },
|
||||
);
|
||||
async move {
|
||||
let _: proto::RemoveParticipantResponse = response.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue