Skip to content

Commit d93154a

Browse files
ali-behjatiReisen
authored andcommitted
Fix ping problem from client
1 parent 866eace commit d93154a

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

hermes/src/api/ws.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,17 @@ use {
3636
},
3737
std::{
3838
collections::HashMap,
39+
pin::Pin,
3940
sync::atomic::{
4041
AtomicUsize,
4142
Ordering,
4243
},
44+
time::Duration,
4345
},
4446
tokio::sync::mpsc,
4547
};
4648

49+
pub const PING_INTERVAL_DURATION: Duration = Duration::from_secs(30);
4750

4851
pub async fn ws_route_handler(
4952
ws: WebSocketUpgrade,
@@ -83,6 +86,8 @@ pub struct Subscriber {
8386
receiver: SplitStream<WebSocket>,
8487
sender: SplitSink<WebSocket, Message>,
8588
price_feeds_with_config: HashMap<PriceIdentifier, PriceFeedClientConfig>,
89+
ping_interval_future: Pin<Box<tokio::time::Sleep>>,
90+
responded_to_ping: bool,
8691
}
8792

8893
impl Subscriber {
@@ -101,6 +106,8 @@ impl Subscriber {
101106
receiver,
102107
sender,
103108
price_feeds_with_config: HashMap::new(),
109+
ping_interval_future: Box::pin(tokio::time::sleep(PING_INTERVAL_DURATION)),
110+
responded_to_ping: true, // We start with true so we don't close the connection immediately
104111
}
105112
}
106113

@@ -131,6 +138,16 @@ impl Subscriber {
131138
Some(message_or_err) => self.handle_client_message(message_or_err?).await?
132139
}
133140
},
141+
_ = &mut self.ping_interval_future => {
142+
if !self.responded_to_ping {
143+
log::debug!("Subscriber {} did not respond to ping, closing connection.", self.id);
144+
self.closed = true;
145+
return Ok(());
146+
}
147+
self.responded_to_ping = false;
148+
self.sender.send(Message::Ping(vec![])).await?;
149+
self.ping_interval_future = Box::pin(tokio::time::sleep(PING_INTERVAL_DURATION));
150+
}
134151
}
135152

136153
Ok(())
@@ -180,6 +197,14 @@ impl Subscriber {
180197
let maybe_client_message = match message {
181198
Message::Text(text) => serde_json::from_str::<ClientMessage>(&text),
182199
Message::Binary(data) => serde_json::from_slice::<ClientMessage>(&data),
200+
Message::Ping(_) => {
201+
// Axum will send Pong automatically
202+
return Ok(());
203+
}
204+
Message::Pong(_) => {
205+
self.responded_to_ping = true;
206+
return Ok(());
207+
}
183208
_ => {
184209
return Ok(());
185210
}
@@ -188,7 +213,7 @@ impl Subscriber {
188213
match maybe_client_message {
189214
Err(e) => {
190215
self.sender
191-
.feed(
216+
.send(
192217
serde_json::to_string(&ServerMessage::Response(
193218
ServerResponseMessage::Err {
194219
error: e.to_string(),

0 commit comments

Comments
 (0)