Skip to content

Commit

Permalink
feat(socketio): send close reason when emitting Event::Close
Browse files Browse the repository at this point in the history
Previously, when we emitted an Event::Close, we didn't specify a
reason for why this event was emitted. When implementing the close
notification on unexpected transport closes, we started sending
'transport close' as the payload for the close event.

We now decided to do this more consistently and added a close reason
when emitting the Event::Close, so that the client better knows
why this event was emitted.
  • Loading branch information
sirkrypt0 committed Sep 24, 2024
1 parent acc524a commit 0540579
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
15 changes: 9 additions & 6 deletions socketio/src/asynchronous/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
asynchronous::socket::Socket as InnerSocket,
error::{Error, Result},
packet::{Packet, PacketId},
Event, Payload,
CloseReason, Event, Payload,
};

#[derive(Default)]
Expand Down Expand Up @@ -168,7 +168,7 @@ impl Client {
// We don't need to do that in the other cases, since proper server close
// and manual client close are handled explicitly.
if let Some(err) = client_clone
.callback(&Event::Close, "transport close")
.callback(&Event::Close, CloseReason::TransportClose.as_str())
.await
.err()
{
Expand Down Expand Up @@ -524,7 +524,8 @@ impl Client {
}
PacketId::Disconnect => {
*(self.disconnect_reason.write().await) = DisconnectReason::Server;
self.callback(&Event::Close, "").await?;
self.callback(&Event::Close, CloseReason::IOServerDisconnect.as_str())
.await?;
}
PacketId::ConnectError => {
self.callback(
Expand Down Expand Up @@ -604,8 +605,7 @@ mod test {
},
error::Result,
packet::{Packet, PacketId},
Event,
Payload, TransportType,
CloseReason, Event, Payload, TransportType,
};

#[tokio::test]
Expand Down Expand Up @@ -977,7 +977,10 @@ mod test {
let rx_timeout = timeout(Duration::from_secs(1), rx.recv()).await;
assert!(rx_timeout.is_ok());

assert_eq!(rx_timeout.unwrap(), Some(Payload::from("transport close")));
assert_eq!(
rx_timeout.unwrap(),
Some(Payload::from(CloseReason::TransportClose.as_str()))
);

Ok(())
}
Expand Down
6 changes: 3 additions & 3 deletions socketio/src/client/raw_client.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::callback::Callback;
use crate::packet::{Packet, PacketId};
use crate::Error;
pub(crate) use crate::{event::Event, payload::Payload};
pub(crate) use crate::{event::CloseReason, event::Event, payload::Payload};
use rand::{thread_rng, Rng};
use serde_json::Value;

Expand Down Expand Up @@ -149,7 +149,7 @@ impl RawClient {
let _ = self.socket.send(disconnect_packet);
self.socket.disconnect()?;

let _ = self.callback(&Event::Close, ""); // trigger on_close
let _ = self.callback(&Event::Close, CloseReason::IOClientDisconnect.as_str()); // trigger on_close
Ok(())
}

Expand Down Expand Up @@ -372,7 +372,7 @@ impl RawClient {
self.callback(&Event::Connect, "")?;
}
PacketId::Disconnect => {
self.callback(&Event::Close, "")?;
self.callback(&Event::Close, CloseReason::IOServerDisconnect.as_str())?;
}
PacketId::ConnectError => {
self.callback(
Expand Down
35 changes: 35 additions & 0 deletions socketio/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,38 @@ impl Display for Event {
f.write_str(self.as_str())
}
}

/// A `CloseReason` is the payload of the [`Event::Close`] and specifies the reason for
/// why it was fired.
/// These are aligned with the official Socket.IO disconnect reasons, see
/// https://socket.io/docs/v4/client-socket-instance/#disconnect
#[derive(Debug, PartialEq, PartialOrd, Clone, Eq, Hash)]
pub enum CloseReason {
IOServerDisconnect,
IOClientDisconnect,
TransportClose,
}

impl CloseReason {
pub fn as_str(&self) -> &str {
match self {
// Inspired by https://github.com/socketio/socket.io/blob/d0fc72042068e7eaef448941add617f05e1ec236/packages/socket.io-client/lib/socket.ts#L865
CloseReason::IOServerDisconnect => "io server disconnect",
// Inspired by https://github.com/socketio/socket.io/blob/d0fc72042068e7eaef448941add617f05e1ec236/packages/socket.io-client/lib/socket.ts#L911
CloseReason::IOClientDisconnect => "io client disconnect",
CloseReason::TransportClose => "transport close",
}
}
}

impl From<CloseReason> for String {
fn from(event: CloseReason) -> Self {
Self::from(event.as_str())
}
}

impl Display for CloseReason {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_str(self.as_str())
}
}
2 changes: 1 addition & 1 deletion socketio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ pub mod asynchronous;

pub use error::Error;

pub use {event::Event, payload::Payload};
pub use {event::CloseReason, event::Event, payload::Payload};

pub use client::{ClientBuilder, RawClient, TransportType};

Expand Down

0 comments on commit 0540579

Please sign in to comment.