···11uniffi::setup_scaffolding!();
2233pub mod c2pa;
44-pub mod endpoint;
54pub mod error;
66-pub mod public_key;
75pub mod node;
88-pub mod receiver;
99-pub mod sender;
106pub mod node_addr;
1111-1212-mod api;
77+pub mod public_key;
-150
rust/iroh-streamplace/src/receiver.rs
···11-use std::sync::Arc;
22-33-use iroh::protocol::Router;
44-55-use crate::{api::Api, endpoint::Endpoint, error::Error, public_key::PublicKey, node_addr::NodeAddr};
66-77-#[derive(uniffi::Object)]
88-pub struct Receiver {
99- endpoint: Endpoint,
1010- _api: Api,
1111- _router: iroh::protocol::Router,
1212-}
1313-1414-#[uniffi::export]
1515-impl Receiver {
1616- /// Create a new receiver.
1717- #[uniffi::constructor(async_runtime = "tokio")]
1818- pub async fn new(
1919- endpoint: &Endpoint,
2020- handler: Arc<dyn DataHandlerOld>,
2121- ) -> Result<Receiver, Error> {
2222- let api = Api::spawn_with_handler(&endpoint.endpoint, move |id, data| {
2323- let handler = handler.clone();
2424- Box::pin(async move {
2525- handler.handle_data(id, data).await;
2626- })
2727- });
2828- let router = Router::builder(endpoint.endpoint.clone())
2929- .accept(Api::ALPN, api.expose())
3030- .spawn();
3131-3232- Ok(Receiver {
3333- endpoint: endpoint.clone(),
3434- _api: api,
3535- _router: router,
3636- })
3737- }
3838-3939- /// Subscribe to the given topic on the remote.
4040- #[uniffi::method(async_runtime = "tokio")]
4141- pub async fn subscribe(&self, remote_id: Arc<PublicKey>, topic: &str) -> Result<(), Error> {
4242- let remote_id: iroh::NodeId = remote_id.as_ref().into();
4343- let api = Api::connect(self.endpoint.endpoint.clone(), remote_id);
4444- api.subscribe(topic.to_string(), self.endpoint.endpoint.node_id())
4545- .await?;
4646- Ok(())
4747- }
4848-4949- /// Unsubscribe from this topic on the remote.
5050- #[uniffi::method(async_runtime = "tokio")]
5151- pub async fn unsubscribe(
5252- &self,
5353- remote_id: Arc<PublicKey>,
5454- topic: &str,
5555- ) -> Result<(), Error> {
5656- let remote_id: iroh::NodeId = remote_id.as_ref().into();
5757- let api = Api::connect(self.endpoint.endpoint.clone(), remote_id);
5858- api.unsubscribe(topic.to_string(), self.endpoint.endpoint.node_id())
5959- .await?;
6060- Ok(())
6161- }
6262-6363- #[uniffi::method(async_runtime = "tokio")]
6464- pub async fn node_addr(&self) -> NodeAddr {
6565- self.endpoint.node_addr().await
6666- }
6767-}
6868-6969-#[uniffi::export(with_foreign)]
7070-#[async_trait::async_trait]
7171-pub trait DataHandlerOld: Send + Sync {
7272- async fn handle_data(&self, topic: String, data: Vec<u8>);
7373-}
7474-7575-#[cfg(test)]
7676-mod tests {
7777-7878- use super::*;
7979- use crate::sender::Sender;
8080-8181- #[tokio::test]
8282- async fn test_roundtrip() {
8383- tracing_subscriber::fmt()
8484- .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
8585- .init();
8686-8787- let ep1 = Endpoint::new().await.unwrap();
8888- let sender = Sender::new(&ep1).await.unwrap();
8989-9090- let (s, mut r) = tokio::sync::mpsc::channel(5);
9191-9292- #[derive(Debug, Clone)]
9393- struct TestHandler {
9494- messages: tokio::sync::mpsc::Sender<(String, Vec<u8>)>,
9595- }
9696-9797- #[async_trait::async_trait]
9898- impl DataHandlerOld for TestHandler {
9999- async fn handle_data(&self, topic: String, data: Vec<u8>) {
100100- self.messages.send((topic, data)).await.unwrap();
101101- }
102102- }
103103-104104- let handler = TestHandler { messages: s };
105105- let ep2 = Endpoint::new().await.unwrap();
106106- let receiver = Receiver::new(&ep2, Arc::new(handler.clone()))
107107- .await
108108- .unwrap();
109109-110110- let sender_addr = sender.node_addr().await;
111111- println!("sender addr: {sender_addr:?}");
112112-113113- let receiver_addr = receiver.node_addr().await;
114114- println!("recv addr: {receiver_addr:?}");
115115-116116- // subscribe
117117- receiver
118118- .subscribe(Arc::new(sender_addr.node_id()), "foo")
119119- .await
120120- .unwrap();
121121-122122- // send a few messages
123123- for i in 0u8..5 {
124124- sender.send("foo", &[i, 0, 0, 0]).await.unwrap();
125125- }
126126-127127- // make sure the receiver got them
128128- for i in 0u8..5 {
129129- let (topic, msg) = r.recv().await.unwrap();
130130- assert_eq!(topic, "foo");
131131- assert_eq!(msg, vec![i, 0, 0, 0]);
132132- }
133133-134134- // unsubscribe
135135- receiver
136136- .unsubscribe(Arc::new(sender_addr.node_id()), "foo")
137137- .await
138138- .unwrap();
139139-140140- // send a message, shouldn't error
141141- sender.send("foo", &[1]).await.unwrap();
142142-143143- // no message received, times out
144144- let res = tokio::time::timeout(std::time::Duration::from_millis(200), async {
145145- r.recv().await.unwrap();
146146- })
147147- .await;
148148- assert!(res.is_err());
149149- }
150150-}
-43
rust/iroh-streamplace/src/sender.rs
···11-use bytes::Bytes;
22-use iroh::protocol::Router;
33-44-use crate::{api::Api, c2pa::SPError, endpoint::Endpoint, error::Error, node_addr::NodeAddr};
55-66-#[derive(uniffi::Object)]
77-pub struct Sender {
88- endpoint: Endpoint,
99- api: Api,
1010- _router: iroh::protocol::Router,
1111-}
1212-1313-#[uniffi::export]
1414-impl Sender {
1515- /// Create a new sender.
1616- #[uniffi::constructor(async_runtime = "tokio")]
1717- pub async fn new(endpoint: &Endpoint) -> Sender {
1818- let api = Api::spawn(&endpoint.endpoint);
1919- let router = Router::builder(endpoint.endpoint.clone())
2020- .accept(Api::ALPN, api.expose())
2121- .spawn();
2222-2323- Sender {
2424- endpoint: endpoint.clone(),
2525- api,
2626- _router: router,
2727- }
2828- }
2929-3030- /// Sends the given data to all subscribers that have subscribed to this `key`.
3131- #[uniffi::method(async_runtime = "tokio")]
3232- pub async fn send(&self, key: &str, data: &[u8]) -> Result<(), Error> {
3333- self.api
3434- .send_segment(key.to_string(), Bytes::copy_from_slice(data))
3535- .await?;
3636- Ok(())
3737- }
3838-3939- #[uniffi::method(async_runtime = "tokio")]
4040- pub async fn node_addr(&self) -> NodeAddr {
4141- self.endpoint.node_addr().await
4242- }
4343-}