Skip to content

Commit

Permalink
在客户端因网络原因/主动原因断线时,发送事件 (#88)
Browse files Browse the repository at this point in the history
* send event when client manually disconnect or by network

* update
  • Loading branch information
LaoLittle authored Dec 1, 2022
1 parent 4c7b28f commit 823f19b
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 3 deletions.
28 changes: 28 additions & 0 deletions ricq/src/client/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use ricq_core::structs::{
};
use ricq_core::{jce, RQResult};

use crate::client::NetworkStatus;
use crate::structs::{FriendMessage, GroupMessage};
use crate::Client;

Expand Down Expand Up @@ -120,3 +121,30 @@ impl FriendAudioMessageEvent {

pub type KickedOfflineEvent = EventWithClient<jce::RequestPushForceOffline>;
pub type MSFOfflineEvent = EventWithClient<jce::RequestMSFForceOffline>;

#[derive(Copy, Clone, Debug)]
#[repr(u8)]
pub enum DisconnectReason {
/// 主动断开
Actively(NetworkStatus),
/// 网络原因
Network,
}

impl DisconnectReason {
/// 客户端网络状态
pub fn status(&self) -> NetworkStatus {
match self {
Self::Actively(s) => *s,
Self::Network => NetworkStatus::NetworkOffline,
}
}
}

pub type ClientDisconnect = EventWithClient<DisconnectReason>;

impl ClientDisconnect {
pub fn reason(&self) -> DisconnectReason {
self.inner
}
}
5 changes: 5 additions & 0 deletions ricq/src/client/handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ pub enum QEvent {
/// 服务端强制下线
/// 不能用于掉线重连,掉线重连以 start 返回为准
MSFOffline(MSFOfflineEvent),
/// 网络原因/客户端主动掉线
/// 可用于掉线重连
ClientDisconnect(ClientDisconnect),
}

/// 处理外发数据的接口
Expand Down Expand Up @@ -157,6 +160,7 @@ pub trait PartlyHandler: Sync {
async fn handle_member_permission_change(&self, _event: MemberPermissionChangeEvent) {}
async fn handle_kicked_offline(&self, _event: KickedOfflineEvent) {}
async fn handle_msf_offline(&self, _event: MSFOfflineEvent) {}
async fn handle_client_disconnect(&self, _event: ClientDisconnect) {}
}

#[async_trait]
Expand Down Expand Up @@ -188,6 +192,7 @@ where
QEvent::MemberPermissionChange(m) => self.handle_member_permission_change(m).await,
QEvent::KickedOffline(m) => self.handle_kicked_offline(m).await,
QEvent::MSFOffline(m) => self.handle_msf_offline(m).await,
QEvent::ClientDisconnect(m) => self.handle_client_disconnect(m).await,
}
}
}
1 change: 1 addition & 0 deletions ricq/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ impl Drop for Client {
}
}

#[derive(Copy, Clone, Debug)]
#[repr(u8)]
pub enum NetworkStatus {
// 未启动
Expand Down
41 changes: 38 additions & 3 deletions ricq/src/client/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::time::Duration;

use crate::client::event::{ClientDisconnect, DisconnectReason};
use async_trait::async_trait;
use bytes::Bytes;
use futures_util::{SinkExt, StreamExt};
Expand All @@ -13,6 +14,7 @@ use tokio_util::codec::LengthDelimitedCodec;

use crate::client::tcp::tcp_connect_fastest;
use crate::client::NetworkStatus;
use crate::handler::QEvent;

use super::Client;

Expand Down Expand Up @@ -63,9 +65,42 @@ impl crate::Client {
.store(NetworkStatus::Running as u8, Ordering::Relaxed);
self.net_loop(stream).await; // 阻塞到断开
self.disconnect();
if self.get_status() == (NetworkStatus::Running as u8) {
self.status
.store(NetworkStatus::NetworkOffline as u8, Ordering::Relaxed);
self.online.store(false, Ordering::Relaxed);

match self.status.compare_exchange(
NetworkStatus::Running as u8,
NetworkStatus::NetworkOffline as u8,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => {
self.handler
.handle(QEvent::ClientDisconnect(ClientDisconnect {
client: Arc::clone(self),
inner: DisconnectReason::Network,
}))
.await;
}
Err(status) => {
self.handler
.handle(QEvent::ClientDisconnect(ClientDisconnect {
client: Arc::clone(self),
inner: {
let network = match status {
0 => NetworkStatus::Unknown,
1 => NetworkStatus::Running,
2 => NetworkStatus::Stop,
3 => NetworkStatus::Drop,
5 => NetworkStatus::KickedOffline,
6 => NetworkStatus::MsfOffline,
_ => NetworkStatus::Unknown,
};

DisconnectReason::Actively(network)
},
}))
.await;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

0 comments on commit 823f19b

Please sign in to comment.