@@ -9,12 +9,23 @@ use crate::client::callback::{SocketAnyCallback, SocketCallback};
9
9
use crate :: error:: Result ;
10
10
use std:: collections:: HashMap ;
11
11
use std:: ops:: DerefMut ;
12
- use std:: sync:: { Arc , Mutex } ;
12
+ use std:: sync:: { Arc , Mutex , RwLock } ;
13
13
use std:: time:: Duration ;
14
14
use std:: time:: Instant ;
15
15
16
16
use crate :: socket:: Socket as InnerSocket ;
17
17
18
+ #[ derive( Default , Clone , Copy , PartialEq ) ]
19
+ pub enum DisconnectReason {
20
+ /// There is no known reason for the disconnect; likely a network error
21
+ #[ default]
22
+ Unknown ,
23
+ /// The user disconnected manually
24
+ Manual ,
25
+ /// The server disconnected
26
+ Server ,
27
+ }
28
+
18
29
/// Represents an `Ack` as given back to the caller. Holds the internal `id` as
19
30
/// well as the current ack'ed state. Holds data which will be accessible as
20
31
/// soon as the ack'ed state is set to true. An `Ack` that didn't get ack'ed
@@ -41,6 +52,7 @@ pub struct RawClient {
41
52
nsp : String ,
42
53
// Data send in the opening packet (commonly used as for auth)
43
54
auth : Option < Value > ,
55
+ pub ( crate ) disconnect_reason : Arc < RwLock < DisconnectReason > > ,
44
56
}
45
57
46
58
impl RawClient {
@@ -62,6 +74,7 @@ impl RawClient {
62
74
on_any,
63
75
outstanding_acks : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
64
76
auth,
77
+ disconnect_reason : Arc :: new ( RwLock :: new ( DisconnectReason :: default ( ) ) ) ,
65
78
} )
66
79
}
67
80
@@ -142,7 +155,14 @@ impl RawClient {
142
155
///
143
156
/// ```
144
157
pub fn disconnect ( & self ) -> Result < ( ) > {
145
- let disconnect_packet =
158
+ * ( self . disconnect_reason . write ( ) ?) = DisconnectReason :: Manual ;
159
+ self . do_disconnect ( )
160
+ }
161
+
162
+ /// Disconnects this client the same way as `disconnect()` but
163
+ /// without setting the `DisconnectReason` to `DisconnectReason::Manual`
164
+ pub fn do_disconnect ( & self ) -> Result < ( ) > {
165
+ let disconnect_packet =
146
166
Packet :: new ( PacketId :: Disconnect , self . nsp . clone ( ) , None , None , 0 , None ) ;
147
167
148
168
// TODO: logging
@@ -153,6 +173,10 @@ impl RawClient {
153
173
Ok ( ( ) )
154
174
}
155
175
176
+ pub fn get_disconnect_reason ( & self ) -> DisconnectReason {
177
+ * self . disconnect_reason . read ( ) . unwrap ( )
178
+ }
179
+
156
180
/// Sends a message to the server but `alloc`s an `ack` to check whether the
157
181
/// server responded in a given time span. This message takes an event, which
158
182
/// could either be one of the common events like "message" or "error" or a
@@ -222,18 +246,32 @@ impl RawClient {
222
246
}
223
247
224
248
pub ( crate ) fn poll ( & self ) -> Result < Option < Packet > > {
249
+ {
250
+ let disconnect_reason = * self . disconnect_reason . read ( ) ?;
251
+ if disconnect_reason == DisconnectReason :: Manual {
252
+ // If disconnected manually, return Ok(None) to end iterator
253
+ return Ok ( None ) ;
254
+ }
255
+ }
225
256
loop {
226
257
match self . socket . poll ( ) {
227
258
Err ( err) => {
228
- self . callback ( & Event :: Error , err. to_string ( ) ) ?;
229
- return Err ( err) ;
259
+ // Check if the disconnection was manual
260
+ let disconnect_reason = * self . disconnect_reason . read ( ) ?;
261
+ if disconnect_reason == DisconnectReason :: Manual {
262
+ // Return Ok(None) to signal the end of the iterator
263
+ return Ok ( None ) ;
264
+ } else {
265
+ self . callback ( & Event :: Error , err. to_string ( ) ) ?;
266
+ return Err ( err) ;
267
+ }
230
268
}
231
269
Ok ( Some ( packet) ) => {
232
270
if packet. nsp == self . nsp {
233
271
self . handle_socketio_packet ( & packet) ?;
234
272
return Ok ( Some ( packet) ) ;
235
273
} else {
236
- // Not our namespace continue polling
274
+ // Not our namespace, continue polling
237
275
}
238
276
}
239
277
Ok ( None ) => return Ok ( None ) ,
@@ -369,9 +407,11 @@ impl RawClient {
369
407
}
370
408
}
371
409
PacketId :: Connect => {
410
+ * ( self . disconnect_reason . write ( ) ?) = DisconnectReason :: default ( ) ;
372
411
self . callback ( & Event :: Connect , "" ) ?;
373
412
}
374
413
PacketId :: Disconnect => {
414
+ * ( self . disconnect_reason . write ( ) ?) = DisconnectReason :: Server ;
375
415
self . callback ( & Event :: Close , "" ) ?;
376
416
}
377
417
PacketId :: ConnectError => {
0 commit comments