Client

Struct Client 

Source
pub struct Client { /* private fields */ }

Implementations§

Source§

impl Client

Source

pub fn new(server: ThreemaServer, creds: Credentials) -> Self

Examples found in repository?
examples/chatwith.rs (line 83)
70async fn main(){
71    env_logger::init();
72    let argv: Vec<_> = std::env::args().collect();
73    if argv.len() != 3 {
74        eprintln!("usage: {} CREDENTIALS-FILE CONTACT", argv[0]);
75        std::process::exit(1);
76    }
77    let creds = threema_client::import::json_file::from_file(&argv[1]).expect("could not read credentials json");
78    let contact = ThreemaID::try_from(argv[2].as_str()).expect("invalid ID");
79    let contact_pubkey = directory_api::Client::default().get_pubkey(&contact).await.expect("could not get public key");
80    let peer = threema_client::Peer{id: contact, pk: contact_pubkey};
81
82    let server = ThreemaServer {addr: SERVER.to_string(), pk: naclbox::PublicKey::from_slice(b"E\x0b\x97W5'\x9f\xde\xcb3\x13d\x8f_\xc6\xee\x9f\xf46\x0e\xa9*\x8c\x17Q\xc6a\xe4\xc0\xd8\xc9\t").unwrap()};
83    let messenger = Arc::new(messaging_client::Client::new(server, creds.clone()));
84
85    let recver = tokio::spawn(recv_print(Arc::clone(&messenger), peer.clone(), creds.clone()));
86    let mut stdin = tokio::io::BufReader::new(tokio::io::stdin());
87    loop {
88        let mut line = String::new();
89        match stdin.read_line(&mut line).await {
90            Err(e) => {
91                eprintln!("{}", e);
92                break;
93            }
94            Ok(0) => { break; }
95            Ok(_) => {
96                let mut plain = threema_client::msg_types::TEXT.to_le_bytes().to_vec();
97                plain.extend_from_slice(&line.trim_end().as_bytes());
98                let m = threema_client::transport::BoxedMessage::encrypt(&creds, "hi", &peer, plain, 0);
99                let sent = messenger.send_message(m).await;
100                if let Err(c) = sent {
101                    println!("{:?}", c);
102                    break;
103                }
104            }
105        }
106    }
107    messenger.shutdown();
108    eprintln!("waiting for receiver to quit...");
109    recver.await.unwrap();
110}
Source

pub async fn event(&self) -> Option<Event>

Wait for next event

Examples found in repository?
examples/chatwith.rs (line 42)
41async fn recv_print(c: Arc<messaging_client::Client>, peer: Peer, creds: Credentials){
42    while let Some(e) =  c.event().await {
43        match e {
44            threema_client::messaging_client::Event::BoxedMessage(m) => {
45                if m.envelope.sender != peer.id {
46                    println!("new message from {} ({})", m.envelope.nickname, m.envelope.sender);
47                }
48                else {
49                    match m.open(&peer.pk, &creds.sk) {
50                        Ok(plain) => {
51                            let ackit = handle_message(&m.envelope, &plain).await;
52                            if ackit {
53                                let _ = c.send_ack(&m.envelope.sender_ack()).await;
54                            }
55                        }
56                        Err(e) => {
57                            log::warn!("invalid message: {}", e);
58                        }
59                    }
60                }
61            }
62            unhandled => {
63                println!("Unhandled Event: {:?}", unhandled);
64            }
65        }
66    }
67}
Source

pub async fn send_message(&self, msg: BoxedMessage) -> Result<(), Closed>

Upload message to the Server. When the function awaits the first time, the message is queued locally and will eventually be sent by the connection task.

Examples found in repository?
examples/chatwith.rs (line 99)
70async fn main(){
71    env_logger::init();
72    let argv: Vec<_> = std::env::args().collect();
73    if argv.len() != 3 {
74        eprintln!("usage: {} CREDENTIALS-FILE CONTACT", argv[0]);
75        std::process::exit(1);
76    }
77    let creds = threema_client::import::json_file::from_file(&argv[1]).expect("could not read credentials json");
78    let contact = ThreemaID::try_from(argv[2].as_str()).expect("invalid ID");
79    let contact_pubkey = directory_api::Client::default().get_pubkey(&contact).await.expect("could not get public key");
80    let peer = threema_client::Peer{id: contact, pk: contact_pubkey};
81
82    let server = ThreemaServer {addr: SERVER.to_string(), pk: naclbox::PublicKey::from_slice(b"E\x0b\x97W5'\x9f\xde\xcb3\x13d\x8f_\xc6\xee\x9f\xf46\x0e\xa9*\x8c\x17Q\xc6a\xe4\xc0\xd8\xc9\t").unwrap()};
83    let messenger = Arc::new(messaging_client::Client::new(server, creds.clone()));
84
85    let recver = tokio::spawn(recv_print(Arc::clone(&messenger), peer.clone(), creds.clone()));
86    let mut stdin = tokio::io::BufReader::new(tokio::io::stdin());
87    loop {
88        let mut line = String::new();
89        match stdin.read_line(&mut line).await {
90            Err(e) => {
91                eprintln!("{}", e);
92                break;
93            }
94            Ok(0) => { break; }
95            Ok(_) => {
96                let mut plain = threema_client::msg_types::TEXT.to_le_bytes().to_vec();
97                plain.extend_from_slice(&line.trim_end().as_bytes());
98                let m = threema_client::transport::BoxedMessage::encrypt(&creds, "hi", &peer, plain, 0);
99                let sent = messenger.send_message(m).await;
100                if let Err(c) = sent {
101                    println!("{:?}", c);
102                    break;
103                }
104            }
105        }
106    }
107    messenger.shutdown();
108    eprintln!("waiting for receiver to quit...");
109    recver.await.unwrap();
110}
Source

pub async fn send_ack(&self, ack: &Ack) -> Result<(), Closed>

Examples found in repository?
examples/chatwith.rs (line 53)
41async fn recv_print(c: Arc<messaging_client::Client>, peer: Peer, creds: Credentials){
42    while let Some(e) =  c.event().await {
43        match e {
44            threema_client::messaging_client::Event::BoxedMessage(m) => {
45                if m.envelope.sender != peer.id {
46                    println!("new message from {} ({})", m.envelope.nickname, m.envelope.sender);
47                }
48                else {
49                    match m.open(&peer.pk, &creds.sk) {
50                        Ok(plain) => {
51                            let ackit = handle_message(&m.envelope, &plain).await;
52                            if ackit {
53                                let _ = c.send_ack(&m.envelope.sender_ack()).await;
54                            }
55                        }
56                        Err(e) => {
57                            log::warn!("invalid message: {}", e);
58                        }
59                    }
60                }
61            }
62            unhandled => {
63                println!("Unhandled Event: {:?}", unhandled);
64            }
65        }
66    }
67}
Source

pub fn shutdown(&self)

Currntly, this simply aborts the background tasks TODO: queued messages should be handled somehow!

Examples found in repository?
examples/chatwith.rs (line 107)
70async fn main(){
71    env_logger::init();
72    let argv: Vec<_> = std::env::args().collect();
73    if argv.len() != 3 {
74        eprintln!("usage: {} CREDENTIALS-FILE CONTACT", argv[0]);
75        std::process::exit(1);
76    }
77    let creds = threema_client::import::json_file::from_file(&argv[1]).expect("could not read credentials json");
78    let contact = ThreemaID::try_from(argv[2].as_str()).expect("invalid ID");
79    let contact_pubkey = directory_api::Client::default().get_pubkey(&contact).await.expect("could not get public key");
80    let peer = threema_client::Peer{id: contact, pk: contact_pubkey};
81
82    let server = ThreemaServer {addr: SERVER.to_string(), pk: naclbox::PublicKey::from_slice(b"E\x0b\x97W5'\x9f\xde\xcb3\x13d\x8f_\xc6\xee\x9f\xf46\x0e\xa9*\x8c\x17Q\xc6a\xe4\xc0\xd8\xc9\t").unwrap()};
83    let messenger = Arc::new(messaging_client::Client::new(server, creds.clone()));
84
85    let recver = tokio::spawn(recv_print(Arc::clone(&messenger), peer.clone(), creds.clone()));
86    let mut stdin = tokio::io::BufReader::new(tokio::io::stdin());
87    loop {
88        let mut line = String::new();
89        match stdin.read_line(&mut line).await {
90            Err(e) => {
91                eprintln!("{}", e);
92                break;
93            }
94            Ok(0) => { break; }
95            Ok(_) => {
96                let mut plain = threema_client::msg_types::TEXT.to_le_bytes().to_vec();
97                plain.extend_from_slice(&line.trim_end().as_bytes());
98                let m = threema_client::transport::BoxedMessage::encrypt(&creds, "hi", &peer, plain, 0);
99                let sent = messenger.send_message(m).await;
100                if let Err(c) = sent {
101                    println!("{:?}", c);
102                    break;
103                }
104            }
105        }
106    }
107    messenger.shutdown();
108    eprintln!("waiting for receiver to quit...");
109    recver.await.unwrap();
110}

Auto Trait Implementations§

§

impl !Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl !UnwindSafe for Client

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,