initial commit

This commit is contained in:
Timur Gordon
2025-07-29 01:15:23 +02:00
commit 7d7ff0f0ab
108 changed files with 24713 additions and 0 deletions

View File

@@ -0,0 +1 @@
/target

View File

@@ -0,0 +1,24 @@
[package]
name = "hero-websocket-examples"
version = "0.1.0"
edition = "2021"
[dependencies]
hero_websocket_client = { path = "../client" }
hero_websocket_server = { path = "../server" }
tokio = { version = "1.0", features = ["full"] }
k256 = { version = "0.13", features = ["ecdsa", "sha256"] }
rand = "0.8"
hex = "0.4"
[[bin]]
name = "ping"
path = "src/ping.rs"
[[bin]]
name = "auth"
path = "src/auth.rs"
[[bin]]
name = "play"
path = "src/play.rs"

View File

@@ -0,0 +1,7 @@
## Hero Websocket Interface Examples
A set of end-to-end examples demonstrating the use of the Hero Websocket interface.
### Ping Example
Simple ping example.

View File

@@ -0,0 +1,104 @@
use hero_websocket_client::CircleWsClientBuilder;
use hero_websocket_server::ServerBuilder;
use tokio::signal;
use tokio::time::{sleep, Duration};
use k256::ecdsa::SigningKey;
use k256::elliptic_curve::sec1::ToEncodedPoint;
use rand::rngs::OsRng;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (circle_public_key_hex, circle_private_key_hex) = {
let signing_key = SigningKey::random(&mut OsRng);
let verifying_key = signing_key.verifying_key();
let public_key_bytes = verifying_key.to_encoded_point(false).as_bytes().to_vec();
let private_key_bytes = signing_key.to_bytes().to_vec();
(hex::encode(public_key_bytes), hex::encode(private_key_bytes))
};
println!("🔗 Minimal WebSocket Ping Example");
// Build server
let server = match ServerBuilder::new()
.host("127.0.0.1")
.port(8443)
.redis_url("redis://localhost:6379")
.worker_id("test")
.with_auth()
.build() {
Ok(server) => {
println!("🚀 Built server...");
server
},
Err(e) => {
eprintln!("Failed to build server: {}", e);
return Err(e.into());
}
};
// Start server
println!("🚀 Starting server...");
let (server_task, server_handle) = server.spawn_circle_server().map_err(|e| {
eprintln!("Failed to start server: {}", e);
e
})?;
// Setup signal handling for clean shutdown
let server_handle_clone = server_handle.clone();
tokio::spawn(async move {
signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
println!("\n🔌 Shutting down...");
server_handle_clone.stop(true).await;
std::process::exit(0);
});
// Brief pause for server startup
sleep(Duration::from_millis(200)).await;
// Connect client
let mut client = CircleWsClientBuilder::new(format!("ws://localhost:8443/{}", circle_public_key_hex))
.with_keypair(circle_private_key_hex)
.build();
match client.connect().await {
Ok(_) => println!("✅ Client Connected"),
Err(e) => {
eprintln!("Failed to connect: {}", e);
return Err(e.into());
}
}
// Authenticate
print!("📤 Authenticating... ");
let response = client.authenticate().await;
match response {
Ok(response) => {
println!("📥 {}", response);
}
Err(e) => {
eprintln!("Failed to authenticate: {}", e);
return Err(e.into());
}
}
// Test whoami after authentication
print!("📤 Calling whoami... ");
match client.whoami().await {
Ok(response) => {
println!("📥 Whoami response: {}", response);
}
Err(e) => {
eprintln!("Failed to call whoami: {}", e);
return Err(e.into());
}
}
// Clean shutdown
client.disconnect().await;
server_handle.stop(true).await;
println!("✅ Done");
Ok(())
}

View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View File

@@ -0,0 +1,79 @@
use hero_websocket_client::CircleWsClientBuilder;
use hero_websocket_server::ServerBuilder;
use std::time::Instant;
use tokio::signal;
use tokio::time::{sleep, timeout, Duration};
const CIRCLE_PUBLIC_KEY: &str = "circle_public_key";
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🔗 Minimal WebSocket Ping Example");
// Build server
let server = match ServerBuilder::new()
.host("127.0.0.1")
.port(8443)
.redis_url("redis://localhost:6379")
.worker_id("test")
.build() {
Ok(server) => {
println!("🚀 Built server...");
server
},
Err(e) => {
eprintln!("Failed to build server: {}", e);
return Err(e.into());
}
};
// Start server
println!("🚀 Starting server...");
let (server_task, server_handle) = server.spawn_circle_server().map_err(|e| {
eprintln!("Failed to start server: {}", e);
e
})?;
// Setup signal handling for clean shutdown
let server_handle_clone = server_handle.clone();
tokio::spawn(async move {
signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
println!("\n🔌 Shutting down...");
server_handle_clone.stop(true).await;
std::process::exit(0);
});
// Brief pause for server startup
sleep(Duration::from_millis(200)).await;
// Connect client
let mut client = CircleWsClientBuilder::new(format!("ws://localhost:8443/{}", CIRCLE_PUBLIC_KEY)).build();
match client.connect().await {
Ok(_) => println!("✅ Client Connected"),
Err(e) => {
eprintln!("Failed to connect: {}", e);
return Err(e.into());
}
}
// Send one ping
print!("📤 Ping... ");
let response = client.ping().await;
match response {
Ok(response) => {
println!("📥 {}", response);
}
Err(e) => {
eprintln!("Failed to ping: {}", e);
return Err(e.into());
}
}
// Clean shutdown
client.disconnect().await;
server_handle.stop(true).await;
println!("✅ Done");
Ok(())
}

View File

@@ -0,0 +1,96 @@
use hero_websocket_client::CircleWsClientBuilder;
use hero_websocket_server::ServerBuilder;
use tokio::signal;
use tokio::time::{sleep, Duration};
use k256::ecdsa::SigningKey;
use k256::elliptic_curve::sec1::ToEncodedPoint;
use rand::rngs::OsRng;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (circle_public_key_hex, circle_private_key_hex) = {
let signing_key = SigningKey::random(&mut OsRng);
let verifying_key = signing_key.verifying_key();
let public_key_bytes = verifying_key.to_encoded_point(false).as_bytes().to_vec();
let private_key_bytes = signing_key.to_bytes().to_vec();
(hex::encode(public_key_bytes), hex::encode(private_key_bytes))
};
println!("🔗 Minimal WebSocket Ping Example");
// Build server
let server = match ServerBuilder::new()
.host("127.0.0.1")
.port(8443)
.redis_url("redis://localhost:6379")
.worker_id("test")
.with_auth()
.build() {
Ok(server) => {
println!("🚀 Built server...");
server
},
Err(e) => {
eprintln!("Failed to build server: {}", e);
return Err(e.into());
}
};
// Start server
println!("🚀 Starting server...");
let (server_task, server_handle) = server.spawn_circle_server().map_err(|e| {
eprintln!("Failed to start server: {}", e);
e
})?;
// Setup signal handling for clean shutdown
let server_handle_clone = server_handle.clone();
tokio::spawn(async move {
signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
println!("\n🔌 Shutting down...");
server_handle_clone.stop(true).await;
std::process::exit(0);
});
// Brief pause for server startup
sleep(Duration::from_millis(200)).await;
// Connect client
let mut client = CircleWsClientBuilder::new(format!("ws://localhost:8443/{}", circle_public_key_hex))
.with_keypair(circle_private_key_hex)
.build();
match client.connect().await {
Ok(_) => println!("✅ Client Connected"),
Err(e) => {
eprintln!("Failed to connect: {}", e);
return Err(e.into());
}
}
// Authenticate
print!("📤 Authenticating... ");
let response = client.authenticate().await;
match response {
Ok(response) => {
println!("📥 {}", response);
}
Err(e) => {
eprintln!("Failed to authenticate: {}", e);
return Err(e.into());
}
}
// Test whoami after authentication
print!("📤 Calling whoami... ");
client.play("script".to_string()).await;
// Clean shutdown
client.disconnect().await;
server_handle.stop(true).await;
println!("✅ Done");
Ok(())
}