/// Initiates a BTP connection with the specified account and saves it to the list of connections
/// maintained by the provided service. This is done in the following steps:
/// 1. Initialize a WebSocket connection at the BTP account's URL
/// 2. Send a BTP authorization packet to the peer
/// 3. If successful, consider the BTP connection established and add it to the service
Initiates a BTP connection with the specified account and saves it to the list of connections
maintained by the provided service. This is done in the following steps:
1. Initialize a WebSocket connection at the BTP account's URL
2. Send a BTP authorization packet to the peer
3. If successful, consider the BTP connection established and add it to the service
Initiates a BTP connection with the specified account and saves it to the list of connections maintained by the provided service . This is done in the following steps : 1 . Initialize a WebSocket connection at the BTP account ' s URL 2 . Send a BTP authorization packet to the peer 3 . If successful consider the BTP connection established and add it to the service
pub async fn connect_to_service_account<O, A>(
    account: A,
    error_on_unavailable: bool,
    service: BtpOutgoingService<O, A>,
) -> Result<(), BtpClientError>
where
    O: OutgoingService<A> + Clone + 'static,
    A: BtpAccount + Send + Sync + 'static,
{
    let account_id = account.id();
    let mut url = account
        .get_ilp_over_btp_url()
        .expect("Accounts must have BTP URLs")
        .clone();
    if url.scheme().starts_with("btp+") {
        // Re-parse the URL after stripping off the leading "btp+" prefix.
        // We cannot use set_scheme here because the URL specification
        // does not allow converting between "special" and "non-special"
        // schemes, and "ws" is considered special.
        // The unwrap cannot fail since we've already been given a valid
        // URL, and in this branch we know it begins with "btp+".
        url = Url::parse(&url.into_string()[4..]).unwrap();
    }
    let token = account
        .get_ilp_over_btp_outgoing_token()
        .map(|s| s.to_vec())
        .unwrap_or_default();
    debug!("Connecting to {}", url);
    let (mut connection, _) = connect_async(url.clone())
        .map_err(|err| {
            BtpClientError::CannotConnect(
                account.username().to_string(),
                url.clone(),
                err.to_string(),
            )
        })
        .await?;
    trace!(
        "Connected to account {} (UID: {}) (URI: {}), sending auth packet",
        account.username(),
        account_id,
        url
    );
    // Send BTP authentication
    let auth_packet = Message::binary(
        BtpPacket::Message(BtpMessage {
            request_id: random(),
            protocol_data: vec![
                ProtocolData {
                    protocol_name: "auth".into(),
                    content_type: ContentType::ApplicationOctetStream,
                    data: vec![],
                },
                ProtocolData {
                    protocol_name: "auth_token".into(),
                    content_type: ContentType::TextPlainUtf8,
                    data: token,
                },
            ],
        })
        .to_bytes(),
    );
    // (right now we just assume they'll close the connection if the auth didn't work)
    let result = connection // this just a stream
        .send(auth_packet)
        .await;
    match result {
        Ok(_) => {
            debug!("Connected to account {}'s server", account.id());
            let connection = connection.filter_map(|v| async move { v.ok() });
            service.add_connection(account, connection);
            Ok(())
        }
        Err(err) => {
            let msg = format!("Error sending auth packet on connection {}: {}", url, err);
            error!("{}", msg);
            if error_on_unavailable {
                Err(BtpClientError::Unavailable(msg))
            } else {
                Ok(())
            }
        }
    }
}
pub async fn connect_to_service_account < O , A > ( account : A , error_on_unavailable : bool , service : BtpOutgoingService < O , A > , ) -> Result < ( ) , BtpClientError > where O : OutgoingService < A > + Clone + ' static , A : BtpAccount + Send + Sync + ' static , { let account_id = account . id ( ) ; let mut url = account . get_ilp_over_btp_url ( ) . expect ( " " ) . clone ( ) ; if url . scheme ( ) . starts_with ( " " ) { // Re-parse the URL after stripping off the leading "btp+" prefix. // We cannot use set_scheme here because the URL specification // does not allow converting between "special" and "non-special" // schemes, and "ws" is considered special. // The unwrap cannot fail since we've already been given a valid // URL, and in this branch we know it begins with "btp+". url = Url :: parse ( & url . into_string ( ) [ 4 .. ] ) . unwrap ( ) ; } let token = account . get_ilp_over_btp_outgoing_token ( ) . map ( | s | s . to_vec ( ) ) . unwrap_or_default ( ) ; debug ! ( " " url ) ; let ( mut connection , _ ) = connect_async ( url . clone ( ) ) . map_err ( | err | { BtpClientError :: CannotConnect ( account . username ( ) . to_string ( ) , url . clone ( ) , err . to_string ( ) , ) } ) . await ? ; trace ! ( " " account username ( ) account_id url ) ; // Send BTP authentication let auth_packet = Message :: binary ( BtpPacket :: Message ( BtpMessage { request_id : random ( ) , protocol_data : vec ! [ ProtocolData { protocol_name " " into ( ) content_type ContentType ApplicationOctetStream data vec [ ] } ProtocolData { protocol_name " " into ( ) content_type ContentType TextPlainUtf8 data token } ] , } ) . to_bytes ( ) , ) ; // (right now we just assume they'll close the connection if the auth didn't work) let result = connection // this just a stream . send ( auth_packet ) . await ; match result { Ok ( _ ) => { debug ! ( " " account id ( ) ) ; let connection = connection . filter_map ( | v | async move { v . ok ( ) } ) ; service . add_connection ( account , connection ) ; Ok ( ( ) ) } Err ( err ) => { let msg = format ! ( " " url err ) ; error ! ( " " msg ) ; if error_on_unavailable { Err ( BtpClientError :: Unavailable ( msg ) ) } else { Ok ( ( ) ) } } } }
Initiates a BTP connection with the specified account and saves it to the list of connections
maintained by the provided service.
Initiates a BTP connection with the specified account and saves it to the list of connections maintained by the provided service .
account
A
error_on_unavailable
bool
service
BtpOutgoingService<O, A>