initial commit
This commit is contained in:
		
							
								
								
									
										1
									
								
								interfaces/websocket/examples/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								interfaces/websocket/examples/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/target
 | 
			
		||||
							
								
								
									
										24
									
								
								interfaces/websocket/examples/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								interfaces/websocket/examples/Cargo.toml
									
									
									
									
									
										Normal 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"
 | 
			
		||||
							
								
								
									
										7
									
								
								interfaces/websocket/examples/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								interfaces/websocket/examples/README.md
									
									
									
									
									
										Normal 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.
 | 
			
		||||
							
								
								
									
										104
									
								
								interfaces/websocket/examples/src/auth.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								interfaces/websocket/examples/src/auth.rs
									
									
									
									
									
										Normal 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(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								interfaces/websocket/examples/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								interfaces/websocket/examples/src/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
fn main() {
 | 
			
		||||
    println!("Hello, world!");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								interfaces/websocket/examples/src/ping.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								interfaces/websocket/examples/src/ping.rs
									
									
									
									
									
										Normal 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(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										96
									
								
								interfaces/websocket/examples/src/play.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								interfaces/websocket/examples/src/play.rs
									
									
									
									
									
										Normal 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(())
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user