10
examples/publish_subscribe/Cargo.toml
Normal file
10
examples/publish_subscribe/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "sq-example-publish-subscribe"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
sq-sdk = { path = "../../crates/sq-sdk" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
92
examples/publish_subscribe/src/main.rs
Normal file
92
examples/publish_subscribe/src/main.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use clap::{Parser, Subcommand};
|
||||
use sq_sdk::{Consumer, ConsumerConfig, Producer, ProducerConfig, ProducerMessage};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(about = "SQ publish/subscribe example")]
|
||||
struct Cli {
|
||||
#[arg(long, default_value = "127.0.0.1:6064")]
|
||||
address: String,
|
||||
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Publish N messages to a topic.
|
||||
Publish {
|
||||
#[arg(long, default_value = "demo")]
|
||||
topic: String,
|
||||
#[arg(long, default_value_t = 100)]
|
||||
count: u64,
|
||||
},
|
||||
/// Subscribe to a topic and print received messages.
|
||||
Subscribe {
|
||||
#[arg(long, default_value = "demo")]
|
||||
topic: String,
|
||||
#[arg(long, default_value = "example-group")]
|
||||
group: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
match cli.command {
|
||||
Commands::Publish { topic, count } => {
|
||||
let mut producer = Producer::connect(ProducerConfig {
|
||||
address: cli.address,
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
println!("Publishing {count} messages to topic '{topic}'...");
|
||||
|
||||
for i in 0..count {
|
||||
let msg = ProducerMessage::new(&topic, format!("message-{i}"));
|
||||
let result = producer.send(&topic, None, msg.value.as_slice()).await?;
|
||||
if i % 10 == 0 {
|
||||
println!(" sent {i}/{count} (offset={})", result.offset);
|
||||
}
|
||||
}
|
||||
|
||||
println!("Done. Published {count} messages.");
|
||||
}
|
||||
Commands::Subscribe { topic, group } => {
|
||||
let mut consumer = Consumer::connect(ConsumerConfig {
|
||||
address: cli.address,
|
||||
consumer_group: group.clone(),
|
||||
topic: topic.clone(),
|
||||
auto_commit: true,
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
println!("Subscribing to topic '{topic}' with group '{group}'...");
|
||||
println!("Press Ctrl+C to stop.\n");
|
||||
|
||||
let mut total = 0u64;
|
||||
loop {
|
||||
let messages = consumer.poll().await?;
|
||||
if messages.is_empty() {
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
for msg in &messages {
|
||||
let value = String::from_utf8_lossy(&msg.value);
|
||||
println!(
|
||||
"[offset={} partition={}] {}",
|
||||
msg.offset, msg.partition, value
|
||||
);
|
||||
}
|
||||
|
||||
total += messages.len() as u64;
|
||||
println!(" ({total} messages received so far)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user