Fix sockets issues (#3015)

* Fix sockets issues

* Fix app comp
This commit is contained in:
Geometrically
2024-12-12 13:25:25 -08:00
committed by GitHub
parent 10ef25eabb
commit c970e9c015
32 changed files with 572 additions and 456 deletions

View File

@@ -33,6 +33,7 @@ pub enum ServerToClientMessage {
UserOffline { id: UserId },
FriendStatuses { statuses: Vec<UserStatus> },
FriendRequest { from: UserId },
FriendRequestRejected { from: UserId },
}
#[derive(Deserialize)]
@@ -40,7 +41,7 @@ struct LauncherHeartbeatInit {
code: String,
}
#[get("launcher_heartbeat")]
#[get("launcher_socket")]
pub async fn ws_init(
req: HttpRequest,
pool: Data<PgPool>,
@@ -122,16 +123,12 @@ pub async fn ws_init(
user.id,
ServerToClientMessage::StatusUpdate { status },
&pool,
&redis,
&db,
Some(friends),
)
.await?;
let mut stream = msg_stream
.aggregate_continuations()
// aggregate continuation frames up to 1MiB
.max_continuation_size(2_usize.pow(20));
let mut stream = msg_stream.aggregate_continuations();
actix_web::rt::spawn(async move {
// receive messages from websocket
@@ -168,7 +165,6 @@ pub async fn ws_init(
status: status.clone(),
},
&pool,
&redis,
&db,
None,
)
@@ -180,12 +176,23 @@ pub async fn ws_init(
}
Ok(AggregatedMessage::Close(_)) => {
let _ = close_socket(user.id, &pool, &redis, &db).await;
let _ = close_socket(user.id, &pool, &db).await;
}
Ok(AggregatedMessage::Ping(msg)) => {
if let Some(mut socket) =
db.auth_sockets.get_mut(&user.id.into())
{
let (_, socket) = socket.value_mut();
let _ = socket.pong(&msg).await;
}
}
_ => {}
}
}
let _ = close_socket(user.id, &pool, &db).await;
});
Ok(res)
@@ -195,7 +202,6 @@ pub async fn broadcast_friends(
user_id: UserId,
message: ServerToClientMessage,
pool: &PgPool,
redis: &RedisPool,
sockets: &ActiveSockets,
friends: Option<Vec<FriendItem>>,
) -> Result<(), crate::database::models::DatabaseError> {
@@ -218,17 +224,7 @@ pub async fn broadcast_friends(
{
let (_, socket) = socket.value_mut();
// TODO: bulk close sockets for better perf
if socket.text(serde_json::to_string(&message)?).await.is_err()
{
Box::pin(close_socket(
friend_id.into(),
pool,
redis,
sockets,
))
.await?;
}
let _ = socket.text(serde_json::to_string(&message)?).await;
}
}
}
@@ -239,22 +235,20 @@ pub async fn broadcast_friends(
pub async fn close_socket(
id: UserId,
pool: &PgPool,
redis: &RedisPool,
sockets: &ActiveSockets,
) -> Result<(), crate::database::models::DatabaseError> {
if let Some((_, (_, socket))) = sockets.auth_sockets.remove(&id) {
let _ = socket.close(None).await;
}
broadcast_friends(
id,
ServerToClientMessage::UserOffline { id },
pool,
redis,
sockets,
None,
)
.await?;
broadcast_friends(
id,
ServerToClientMessage::UserOffline { id },
pool,
sockets,
None,
)
.await?;
}
Ok(())
}

View File

@@ -74,8 +74,6 @@ pub async fn add_friend(
async fn send_friend_status(
user_id: UserId,
friend_id: UserId,
pool: &PgPool,
redis: &RedisPool,
sockets: &ActiveSockets,
) -> Result<(), ApiError> {
if let Some(pair) = sockets.auth_sockets.get(&user_id.into()) {
@@ -85,45 +83,21 @@ pub async fn add_friend(
{
let (_, socket) = socket.value_mut();
if socket
let _ = socket
.text(serde_json::to_string(
&ServerToClientMessage::StatusUpdate {
status: friend_status.clone(),
},
)?)
.await
.is_err()
{
close_socket(
friend_id.into(),
pool,
redis,
sockets,
)
.await?;
}
.await;
}
}
Ok(())
}
send_friend_status(
friend.user_id,
friend.friend_id,
&pool,
&redis,
&db,
)
.await?;
send_friend_status(
friend.friend_id,
friend.user_id,
&pool,
&redis,
&db,
)
.await?;
send_friend_status(friend.user_id, friend.friend_id, &db).await?;
send_friend_status(friend.friend_id, friend.user_id, &db).await?;
} else {
if friend.id == user.id.into() {
return Err(ApiError::InvalidInput(
@@ -157,7 +131,7 @@ pub async fn add_friend(
.await
.is_err()
{
close_socket(user.id, &pool, &redis, &db).await?;
close_socket(user.id, &pool, &db).await?;
}
}
}
@@ -177,6 +151,7 @@ pub async fn remove_friend(
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
session_queue: web::Data<AuthQueue>,
db: web::Data<ActiveSockets>,
) -> Result<HttpResponse, ApiError> {
let user = get_user_from_headers(
&req,
@@ -202,6 +177,18 @@ pub async fn remove_friend(
)
.await?;
if let Some(mut socket) = db.auth_sockets.get_mut(&friend.id.into()) {
let (_, socket) = socket.value_mut();
let _ = socket
.text(serde_json::to_string(
&ServerToClientMessage::FriendRequestRejected {
from: user.id,
},
)?)
.await;
}
transaction.commit().await?;
Ok(HttpResponse::NoContent().body(""))