|
@@ -10,6 +10,7 @@ use crate::net::protocols::{ProtocolJobsManager, ProtocolJobsManagerPtr};
|
|
|
use crate::net::utility::sleep;
|
|
use crate::net::utility::sleep;
|
|
|
use crate::net::{ChannelPtr, SettingsPtr};
|
|
use crate::net::{ChannelPtr, SettingsPtr};
|
|
|
|
|
|
|
|
|
|
+/// Protocol for ping-pong keep-alive messages.
|
|
|
pub struct ProtocolPing {
|
|
pub struct ProtocolPing {
|
|
|
channel: ChannelPtr,
|
|
channel: ChannelPtr,
|
|
|
settings: SettingsPtr,
|
|
settings: SettingsPtr,
|
|
@@ -18,6 +19,7 @@ pub struct ProtocolPing {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
impl ProtocolPing {
|
|
impl ProtocolPing {
|
|
|
|
|
+ /// Create a new ping-pong protocol.
|
|
|
pub fn new(channel: ChannelPtr, settings: SettingsPtr) -> Arc<Self> {
|
|
pub fn new(channel: ChannelPtr, settings: SettingsPtr) -> Arc<Self> {
|
|
|
Arc::new(Self {
|
|
Arc::new(Self {
|
|
|
channel: channel.clone(),
|
|
channel: channel.clone(),
|
|
@@ -26,6 +28,9 @@ impl ProtocolPing {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// Starts ping-pong keep-alive messages exchange. Runs ping-pong in the protocol task manager,
|
|
|
|
|
+ /// then queues the reply. run_ping_pong() sends out a ping and waits for pong reply.
|
|
|
|
|
+ /// reply_to_ping() waits for ping and replies with a pong.
|
|
|
pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) {
|
|
pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) {
|
|
|
debug!(target: "net", "ProtocolPing::start() [START]");
|
|
debug!(target: "net", "ProtocolPing::start() [START]");
|
|
|
self.jobsman.clone().start(executor.clone());
|
|
self.jobsman.clone().start(executor.clone());
|
|
@@ -40,8 +45,12 @@ impl ProtocolPing {
|
|
|
debug!(target: "net", "ProtocolPing::start() [END]");
|
|
debug!(target: "net", "ProtocolPing::start() [END]");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// Runs ping-pong protocol. Creates a subscription to pong, then starts a loop. Loop sleeps
|
|
|
|
|
+ /// for the duration of the channel heartbeat, then sends a ping message with a random nonce.
|
|
|
|
|
+ /// Loop starts a timer, waits for the pong reply and insures the nonce is the same.
|
|
|
async fn run_ping_pong(self: Arc<Self>) -> NetResult<()> {
|
|
async fn run_ping_pong(self: Arc<Self>) -> NetResult<()> {
|
|
|
debug!(target: "net", "ProtocolPing::run_ping_pong() [START]");
|
|
debug!(target: "net", "ProtocolPing::run_ping_pong() [START]");
|
|
|
|
|
+ // Creates a subscription to pong message.
|
|
|
let pong_sub = self
|
|
let pong_sub = self
|
|
|
.channel
|
|
.channel
|
|
|
.clone()
|
|
.clone()
|
|
@@ -50,20 +59,20 @@ impl ProtocolPing {
|
|
|
.expect("Missing pong dispatcher!");
|
|
.expect("Missing pong dispatcher!");
|
|
|
|
|
|
|
|
loop {
|
|
loop {
|
|
|
- // Wait channel_heartbeat amount of time
|
|
|
|
|
|
|
+ // Wait channel_heartbeat amount of time.
|
|
|
sleep(self.settings.channel_heartbeat_seconds).await;
|
|
sleep(self.settings.channel_heartbeat_seconds).await;
|
|
|
|
|
|
|
|
- // Create a random nonce
|
|
|
|
|
|
|
+ // Create a random nonce.
|
|
|
let nonce = Self::random_nonce();
|
|
let nonce = Self::random_nonce();
|
|
|
|
|
|
|
|
- // Send ping message
|
|
|
|
|
|
|
+ // Send ping message.
|
|
|
let ping = messages::PingMessage { nonce };
|
|
let ping = messages::PingMessage { nonce };
|
|
|
self.channel.clone().send(ping).await?;
|
|
self.channel.clone().send(ping).await?;
|
|
|
debug!(target: "net", "ProtocolPing::run_ping_pong() send Ping message");
|
|
debug!(target: "net", "ProtocolPing::run_ping_pong() send Ping message");
|
|
|
- // Start the timer for ping timer
|
|
|
|
|
|
|
+ // Start the timer for ping timer.
|
|
|
let start = Instant::now();
|
|
let start = Instant::now();
|
|
|
|
|
|
|
|
- // Wait for pong, check nonce matches
|
|
|
|
|
|
|
+ // Wait for pong, check nonce matches.
|
|
|
let pong_msg = pong_sub.receive().await?;
|
|
let pong_msg = pong_sub.receive().await?;
|
|
|
if pong_msg.nonce != nonce {
|
|
if pong_msg.nonce != nonce {
|
|
|
error!("Wrong nonce for ping reply. Disconnecting from channel.");
|
|
error!("Wrong nonce for ping reply. Disconnecting from channel.");
|
|
@@ -75,8 +84,10 @@ impl ProtocolPing {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// Waits for ping, then replies with pong. Copies ping's nonce into the pong reply.
|
|
|
async fn reply_to_ping(self: Arc<Self>) -> NetResult<()> {
|
|
async fn reply_to_ping(self: Arc<Self>) -> NetResult<()> {
|
|
|
debug!(target: "net", "ProtocolPing::reply_to_ping() [START]");
|
|
debug!(target: "net", "ProtocolPing::reply_to_ping() [START]");
|
|
|
|
|
+ // Creates a subscription to ping message.
|
|
|
let ping_sub = self
|
|
let ping_sub = self
|
|
|
.channel
|
|
.channel
|
|
|
.clone()
|
|
.clone()
|
|
@@ -85,11 +96,11 @@ impl ProtocolPing {
|
|
|
.expect("Missing ping dispatcher!");
|
|
.expect("Missing ping dispatcher!");
|
|
|
|
|
|
|
|
loop {
|
|
loop {
|
|
|
- // Wait for ping, reply with pong that has a matching nonce
|
|
|
|
|
|
|
+ // Wait for ping, reply with pong that has a matching nonce.
|
|
|
let ping = ping_sub.receive().await?;
|
|
let ping = ping_sub.receive().await?;
|
|
|
debug!(target: "net", "ProtocolPing::reply_to_ping() received Ping message");
|
|
debug!(target: "net", "ProtocolPing::reply_to_ping() received Ping message");
|
|
|
|
|
|
|
|
- // Send ping message
|
|
|
|
|
|
|
+ // Send pong message.
|
|
|
let pong = messages::PongMessage { nonce: ping.nonce };
|
|
let pong = messages::PongMessage { nonce: ping.nonce };
|
|
|
self.channel.clone().send(pong).await?;
|
|
self.channel.clone().send(pong).await?;
|
|
|
debug!(target: "net", "ProtocolPing::reply_to_ping() sent Pong reply");
|
|
debug!(target: "net", "ProtocolPing::reply_to_ping() sent Pong reply");
|