enostr

rust nostr lib that works on the web and natively
git clone git://jb55.com/enostr
Log | Files | Refs

pool.rs (2803B)


      1 use crate::relay::message::RelayEvent;
      2 use crate::relay::Relay;
      3 use crate::{ClientMessage, Result};
      4 use ewebsock::WsMessage;
      5 use tracing::{debug, error};
      6 
      7 #[derive(Debug)]
      8 pub struct PoolEvent<'a> {
      9     pub relay: &'a str,
     10     pub event: RelayEvent,
     11 }
     12 
     13 pub struct RelayPool {
     14     pub relays: Vec<Relay>,
     15 }
     16 
     17 impl Default for RelayPool {
     18     fn default() -> RelayPool {
     19         RelayPool { relays: Vec::new() }
     20     }
     21 }
     22 
     23 impl RelayPool {
     24     // Constructs a new, empty RelayPool.
     25     pub fn new() -> RelayPool {
     26         RelayPool { relays: vec![] }
     27     }
     28 
     29     pub fn has(&self, url: &str) -> bool {
     30         for relay in &self.relays {
     31             if &relay.url == url {
     32                 return true;
     33             }
     34         }
     35         return false;
     36     }
     37 
     38     pub fn send(&mut self, cmd: &ClientMessage) {
     39         for relay in &mut self.relays {
     40             relay.send(cmd);
     41         }
     42     }
     43 
     44     pub fn send_to(&mut self, cmd: &ClientMessage, relay_url: &str) {
     45         for relay in &mut self.relays {
     46             if relay.url == relay_url {
     47                 relay.send(cmd);
     48                 return;
     49             }
     50         }
     51     }
     52 
     53     // Adds a websocket url to the RelayPool.
     54     pub fn add_url(
     55         &mut self,
     56         url: String,
     57         wakeup: impl Fn() + Send + Sync + 'static,
     58     ) -> Result<()> {
     59         let relay = Relay::new(url, wakeup)?;
     60 
     61         self.relays.push(relay);
     62 
     63         Ok(())
     64     }
     65 
     66     /// Attempts to receive a pool event from a list of relays. The function searches each relay in the list in order, attempting to receive a message from each. If a message is received, return it. If no message is received from any relays, None is returned.
     67     pub fn try_recv(&mut self) -> Option<PoolEvent<'_>> {
     68         for relay in &mut self.relays {
     69             if let Some(msg) = relay.receiver.try_recv() {
     70                 match msg.try_into() {
     71                     Ok(event) => {
     72                         // let's just handle pongs here.
     73                         // We only need to do this natively.
     74                         #[cfg(not(target_arch = "wasm32"))]
     75                         match event {
     76                             RelayEvent::Other(WsMessage::Ping(ref bs)) => {
     77                                 debug!("pong {}", &relay.url);
     78                                 relay.sender.send(WsMessage::Pong(bs.to_owned()));
     79                             }
     80                             _ => {}
     81                         }
     82 
     83                         return Some(PoolEvent {
     84                             event,
     85                             relay: &relay.url,
     86                         });
     87                     }
     88 
     89                     Err(e) => {
     90                         error!("{:?}", e);
     91                         continue;
     92                     }
     93                 }
     94             }
     95         }
     96 
     97         None
     98     }
     99 }