use super::Gateway;
use crate::error::{
CodeConnCloseCantIdentify, CodeConnCloseCantResume, CodeInvalidSession, Result,
WSCodeBackendAuthenticationFail, WSCodeBackendBotBanned, WSCodeBackendBotOffline,
WSCodeBackendInvalidSeq, WSCodeBackendSessionNoLongerValid, err_invalid_session,
};
use std::sync::atomic::Ordering;
use tracing::{debug, info};
impl Gateway {
pub(super) fn handle_close_code(&mut self, close_code: u16) -> Result<()> {
if close_code == WSCodeBackendAuthenticationFail {
info!("[botrs] 鉴权失败,重置token...");
self.session_id = None;
self.last_seq.store(0, Ordering::Relaxed);
self.is_ready.store(false, Ordering::Relaxed);
}
if Self::cannot_resume_close_code(close_code) {
debug!("[botrs] 无法重连,创建新连接!");
self.session_id = None;
self.last_seq.store(0, Ordering::Relaxed);
self.is_ready.store(false, Ordering::Relaxed);
self.can_reconnect.store(true, Ordering::Relaxed);
Err(err_invalid_session().into())
} else if Self::cannot_identify_close_code(close_code) {
info!("[botrs] 连接关闭且不能重新鉴权,停止连接尝试");
self.session_id = None;
self.last_seq.store(0, Ordering::Relaxed);
self.is_ready.store(false, Ordering::Relaxed);
self.can_reconnect.store(false, Ordering::Relaxed);
Err(crate::error::New(
CodeConnCloseCantIdentify,
format!("websocket closed with code {close_code}"),
)
.into())
} else if !self.can_reconnect.load(Ordering::Relaxed) {
debug!("[botrs] 当前状态不允许重连,停止连接尝试");
Ok(())
} else {
debug!("[botrs] 连接断开,准备重连...");
self.is_ready.store(false, Ordering::Relaxed);
self.can_reconnect.store(true, Ordering::Relaxed);
Ok(())
}
}
pub(super) fn cannot_resume_close_code(close_code: u16) -> bool {
const CODE_INVALID_SESSION: u16 = CodeInvalidSession as u16;
const CODE_CONN_CLOSE_CANT_RESUME: u16 = CodeConnCloseCantResume as u16;
const CODE_SESSION_NO_LONGER_VALID: u16 = WSCodeBackendSessionNoLongerValid;
const CODE_INVALID_SEQ: u16 = WSCodeBackendInvalidSeq;
matches!(
close_code,
CODE_INVALID_SESSION
| CODE_CONN_CLOSE_CANT_RESUME
| CODE_SESSION_NO_LONGER_VALID
| CODE_INVALID_SEQ
)
}
pub(super) fn cannot_identify_close_code(close_code: u16) -> bool {
const CODE_BOT_OFFLINE: u16 = WSCodeBackendBotOffline;
const CODE_BOT_BANNED: u16 = WSCodeBackendBotBanned;
matches!(close_code, CODE_BOT_OFFLINE | CODE_BOT_BANNED)
}
}