mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix clients are disconnecting GRACEFULLY by removing the Disconnect Request from a client, a client now sends a TERMINATE message directly
This commit is contained in:
parent
37d08e93ca
commit
6bb74c9c6f
@ -500,9 +500,9 @@ impl Client {
|
||||
| ClientGeneral::RefundSkill(_)
|
||||
| ClientGeneral::UnlockSkillGroup(_) => &mut self.in_game_stream,
|
||||
//Always possible
|
||||
ClientGeneral::ChatMsg(_)
|
||||
| ClientGeneral::Disconnect
|
||||
| ClientGeneral::Terminate => &mut self.general_stream,
|
||||
ClientGeneral::ChatMsg(_) | ClientGeneral::Terminate => {
|
||||
&mut self.general_stream
|
||||
},
|
||||
};
|
||||
stream.send(msg)
|
||||
},
|
||||
@ -552,9 +552,11 @@ impl Client {
|
||||
}
|
||||
|
||||
/// Send disconnect message to the server
|
||||
pub fn request_logout(&mut self) {
|
||||
debug!("Requesting logout from server");
|
||||
self.send_msg(ClientGeneral::Disconnect);
|
||||
pub fn logout(&mut self) {
|
||||
debug!("Sending logout from server");
|
||||
self.send_msg(ClientGeneral::Terminate);
|
||||
self.registered = false;
|
||||
self.in_game = None;
|
||||
}
|
||||
|
||||
/// Request a state transition to `ClientState::Registered` from an ingame
|
||||
@ -1133,11 +1135,6 @@ impl Client {
|
||||
match msg {
|
||||
ServerGeneral::Disconnect(reason) => match reason {
|
||||
DisconnectReason::Shutdown => return Err(Error::ServerShutdown),
|
||||
DisconnectReason::Requested => {
|
||||
debug!("finally sending ClientMsg::Terminate");
|
||||
frontend_events.push(Event::Disconnect);
|
||||
self.send_msg_err(ClientGeneral::Terminate)?;
|
||||
},
|
||||
DisconnectReason::Kicked(reason) => {
|
||||
debug!("sending ClientMsg::Terminate because we got kicked");
|
||||
frontend_events.push(Event::Kicked(reason));
|
||||
@ -1840,7 +1837,7 @@ impl Drop for Client {
|
||||
fn drop(&mut self) {
|
||||
trace!("Dropping client");
|
||||
if self.registered {
|
||||
if let Err(e) = self.send_msg_err(ClientGeneral::Disconnect) {
|
||||
if let Err(e) = self.send_msg_err(ClientGeneral::Terminate) {
|
||||
warn!(
|
||||
?e,
|
||||
"Error during drop of client, couldn't send disconnect package, is the \
|
||||
|
@ -78,7 +78,6 @@ pub enum ClientGeneral {
|
||||
UnlockSkillGroup(SkillGroupType),
|
||||
//Always possible
|
||||
ChatMsg(String),
|
||||
Disconnect,
|
||||
Terminate,
|
||||
}
|
||||
|
||||
@ -119,9 +118,7 @@ impl ClientMsg {
|
||||
c_type == ClientType::Game && in_game.is_some()
|
||||
},
|
||||
//Always possible
|
||||
ClientGeneral::ChatMsg(_)
|
||||
| ClientGeneral::Disconnect
|
||||
| ClientGeneral::Terminate => true,
|
||||
ClientGeneral::ChatMsg(_) | ClientGeneral::Terminate => true,
|
||||
}
|
||||
},
|
||||
ClientMsg::Ping(_) => true,
|
||||
|
@ -163,8 +163,6 @@ pub enum Notification {
|
||||
pub enum DisconnectReason {
|
||||
/// Server shut down
|
||||
Shutdown,
|
||||
/// Client sent disconnect message
|
||||
Requested,
|
||||
/// Client was kicked
|
||||
Kicked(String),
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ pub struct Client {
|
||||
pub participant: Option<Participant>,
|
||||
pub last_ping: f64,
|
||||
pub login_msg_sent: bool,
|
||||
pub terminate_msg_recv: bool,
|
||||
}
|
||||
|
||||
impl Component for Client {
|
||||
|
@ -143,6 +143,7 @@ impl ConnectionHandler {
|
||||
participant: Some(participant),
|
||||
last_ping: server_data.time,
|
||||
login_msg_sent: false,
|
||||
terminate_msg_recv: false,
|
||||
};
|
||||
|
||||
let package = IncomingClient {
|
||||
|
@ -1,16 +1,9 @@
|
||||
use super::super::SysTimer;
|
||||
use crate::{
|
||||
client::Client,
|
||||
metrics::PlayerMetrics,
|
||||
streams::{GeneralStream, GetStream},
|
||||
};
|
||||
use crate::{client::Client, metrics::PlayerMetrics, streams::GeneralStream};
|
||||
use common::{
|
||||
comp::{ChatMode, UnresolvedChatMsg},
|
||||
event::{EventBus, ServerEvent},
|
||||
msg::{
|
||||
validate_chat_msg, ChatMsgValidationError, ClientGeneral, DisconnectReason, ServerGeneral,
|
||||
MAX_BYTES_CHAT_MSG,
|
||||
},
|
||||
msg::{validate_chat_msg, ChatMsgValidationError, ClientGeneral, MAX_BYTES_CHAT_MSG},
|
||||
span,
|
||||
state::Time,
|
||||
sync::Uid,
|
||||
@ -25,7 +18,6 @@ impl Sys {
|
||||
new_chat_msgs: &mut Vec<(Option<specs::Entity>, UnresolvedChatMsg)>,
|
||||
entity: specs::Entity,
|
||||
client: &mut Client,
|
||||
general_stream: &mut GeneralStream,
|
||||
player_metrics: &ReadExpect<'_, PlayerMetrics>,
|
||||
uids: &ReadStorage<'_, Uid>,
|
||||
chat_modes: &ReadStorage<'_, ChatMode>,
|
||||
@ -52,17 +44,13 @@ impl Sys {
|
||||
}
|
||||
}
|
||||
},
|
||||
ClientGeneral::Disconnect => {
|
||||
general_stream.send(ServerGeneral::Disconnect(DisconnectReason::Requested))?;
|
||||
},
|
||||
ClientGeneral::Terminate => {
|
||||
debug!(?entity, "Client send message to termitate session");
|
||||
player_metrics
|
||||
.clients_disconnected
|
||||
.with_label_values(&["gracefully"])
|
||||
.inc();
|
||||
client.registered = false;
|
||||
client.in_game = None;
|
||||
client.terminate_msg_recv = true;
|
||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||
},
|
||||
_ => unreachable!("not a client_general msg"),
|
||||
@ -110,13 +98,12 @@ impl<'a> System<'a> for Sys {
|
||||
for (entity, client, general_stream) in
|
||||
(&entities, &mut clients, &mut general_streams).join()
|
||||
{
|
||||
let res = super::try_recv_all(general_stream, |general_stream, msg| {
|
||||
let res = super::try_recv_all(general_stream, |_, msg| {
|
||||
Self::handle_general_msg(
|
||||
&mut server_emitter,
|
||||
&mut new_chat_msgs,
|
||||
entity,
|
||||
client,
|
||||
general_stream,
|
||||
&player_metrics,
|
||||
&uids,
|
||||
&chat_modes,
|
||||
|
@ -67,20 +67,14 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
match res {
|
||||
Err(e) => {
|
||||
let reg = client.registered;
|
||||
debug!(
|
||||
?entity,
|
||||
?e,
|
||||
?reg,
|
||||
"network error with client, disconnecting"
|
||||
);
|
||||
if reg {
|
||||
if !client.terminate_msg_recv {
|
||||
debug!(?entity, ?e, "network error with client, disconnecting");
|
||||
player_metrics
|
||||
.clients_disconnected
|
||||
.with_label_values(&["network_error"])
|
||||
.inc();
|
||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||
}
|
||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||
},
|
||||
Ok(1_u64..=u64::MAX) => {
|
||||
// Update client ping.
|
||||
@ -90,15 +84,14 @@ impl<'a> System<'a> for Sys {
|
||||
if time.0 - client.last_ping > settings.client_timeout.as_secs() as f64
|
||||
// Timeout
|
||||
{
|
||||
let reg = client.registered;
|
||||
info!(?entity, ?reg, "timeout error with client, disconnecting");
|
||||
if reg {
|
||||
if !client.terminate_msg_recv {
|
||||
info!(?entity, "timeout error with client, disconnecting");
|
||||
player_metrics
|
||||
.clients_disconnected
|
||||
.with_label_values(&["timeout"])
|
||||
.inc();
|
||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||
}
|
||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||
} else if time.0 - client.last_ping
|
||||
> settings.client_timeout.as_secs() as f64 * 0.5
|
||||
{
|
||||
|
@ -763,7 +763,10 @@ impl PlayState for SessionState {
|
||||
HudEvent::CharacterSelection => {
|
||||
self.client.borrow_mut().request_remove_character()
|
||||
},
|
||||
HudEvent::Logout => self.client.borrow_mut().request_logout(),
|
||||
HudEvent::Logout => {
|
||||
self.client.borrow_mut().logout();
|
||||
return PlayStateResult::Pop;
|
||||
},
|
||||
HudEvent::Quit => {
|
||||
return PlayStateResult::Shutdown;
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user