-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The subscription of websocket does not have an example of broadcasting to all subscribers, hoping to give guidance #697
Comments
Hey @keienWang The result should published to each subscriber however your example is confusing, you should really remove the first Can you share the entire example otherwise I can't re-produce thus? It could be that you only poll the subscription once or something?! Also, we should update the |
source example,I just want to implement an observer pattern and send an external changing value,For example, there are two subscribers, and I want to send new blocks to them at the same time |
Ok, I see the easiest would be use message passing i.e, once a new block/item is produced/changed you send a message to the receiver that implements The idea that something like should work: async fn run_server() -> anyhow::Result<SocketAddr> {
let server = WsServerBuilder::default().build("127.0.0.1:0").await?;
let (tx, rx) = async_channel::unbounded();
let mut module = RpcModule::new(());
tokio::spawn(async move {
let mut i = 4;
loop {
i += 1;
tx.send(i).await.unwrap();
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
}
});
module.register_subscription("subscribe_hello", "s_hello", "unsubscribe_hello", move |_, mut sink, _| {
// required because of the `Fn closure above`
let rx = rx.clone();
tokio::spawn(async move {
sink.pipe_from_stream(rx).await;
});
Ok(())
})?;
let addr = server.local_addr()?;
server.start(module)?;
Ok(addr)
} |
Right, my bad async fn run_server() -> anyhow::Result<SocketAddr> {
let server = WsServerBuilder::default().build("127.0.0.1:0").await?;
let (tx, _) = tokio::sync::broadcast::channel::<i32>(16);
let mut module = RpcModule::new(());
let tx1 = tx.clone();
tokio::spawn(async move {
let mut i = 4;
loop {
i += 1;
tx1.send(i).unwrap();
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
}
});
module.register_subscription("subscribe_hello", "s_hello", "unsubscribe_hello", move |_, mut sink, _| {
// required because of the `Fn closure above`
let mut rx = tx.subscribe();
tokio::spawn(async move {
while let Ok(item) = rx.recv().await {
if let Err(Error::SubscriptionClosed(_)) = sink.send(&item) {
return;
}
}
});
Ok(())
})?;
let addr = server.local_addr()?;
server.start(module)?;
Ok(addr)
} However, I realized that In practice we more or less expect users to create a separate stream for each subscription but if you plan to use something like provided above we should make it a bit more ergonomic to use. |
Closed by #705 |
For example, I want to publish a message to all subscribers, how can I collect all subscribers at this time? In the example, I only see, publish an i:= 4, but I want to change the value of i and then broadcast to each subscriber, how to change it
The text was updated successfully, but these errors were encountered: