diff --git a/socketio/src/asynchronous/client/client.rs b/socketio/src/asynchronous/client/client.rs index f2040c9d..da1d5f09 100644 --- a/socketio/src/asynchronous/client/client.rs +++ b/socketio/src/asynchronous/client/client.rs @@ -19,7 +19,7 @@ use crate::{ asynchronous::socket::Socket as InnerSocket, error::{Error, Result}, packet::{Packet, PacketId}, - Event, Payload, + CloseReason, Event, Payload, }; #[derive(Default)] @@ -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() { @@ -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( @@ -604,8 +605,7 @@ mod test { }, error::Result, packet::{Packet, PacketId}, - Event, - Payload, TransportType, + CloseReason, Event, Payload, TransportType, }; #[tokio::test] @@ -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(()) } diff --git a/socketio/src/client/raw_client.rs b/socketio/src/client/raw_client.rs index 0686683f..865a9ec6 100644 --- a/socketio/src/client/raw_client.rs +++ b/socketio/src/client/raw_client.rs @@ -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; @@ -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(()) } @@ -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( diff --git a/socketio/src/event.rs b/socketio/src/event.rs index 2d2ed1f9..ef1c65a8 100644 --- a/socketio/src/event.rs +++ b/socketio/src/event.rs @@ -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 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()) + } +} diff --git a/socketio/src/lib.rs b/socketio/src/lib.rs index b913eb4d..1445cc82 100644 --- a/socketio/src/lib.rs +++ b/socketio/src/lib.rs @@ -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};