homework: purify power socket server
This commit is contained in:
@@ -4,4 +4,4 @@ name = "smart-house"
|
|||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = { version = "1.49.0", features = ["rt", "net", "io-util", "time", "sync"] }
|
tokio = { version = "1.49.0", features = ["rt", "net", "io-util", "time"] }
|
||||||
|
|||||||
10
smart-house/src/bin/power_socket_client.rs
Normal file
10
smart-house/src/bin/power_socket_client.rs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
use smart_house::PowerSocket;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut power_socket = PowerSocket::connect("127.0.0.1:10001");
|
||||||
|
println!("{}", power_socket.display());
|
||||||
|
std::thread::sleep(Duration::from_secs(2));
|
||||||
|
power_socket.set_on(!power_socket.is_on());
|
||||||
|
println!("{}", power_socket.display());
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, RwLock};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
|
||||||
@@ -12,7 +12,6 @@ fn parse_args() -> SocketAddr {
|
|||||||
.expect("server address should be valid")
|
.expect("server address should be valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct RealPowerSocket {
|
struct RealPowerSocket {
|
||||||
power_rate: f32,
|
power_rate: f32,
|
||||||
on: bool,
|
on: bool,
|
||||||
@@ -25,7 +24,7 @@ const CMD_GET_POWER: u8 = 4;
|
|||||||
|
|
||||||
const TIMEOUT: Duration = Duration::from_secs(5);
|
const TIMEOUT: Duration = Duration::from_secs(5);
|
||||||
|
|
||||||
async fn handle_connection(mut socket: tokio::net::TcpStream, real_power_socket: Arc<tokio::sync::RwLock<RealPowerSocket>>) -> Result<(), std::io::Error> {
|
async fn handle_connection(mut socket: tokio::net::TcpStream, real_power_socket: Arc<RwLock<RealPowerSocket>>) -> Result<(), std::io::Error> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
loop {
|
loop {
|
||||||
let read = tokio::time::timeout(TIMEOUT, socket.read(&mut buf)).await??;
|
let read = tokio::time::timeout(TIMEOUT, socket.read(&mut buf)).await??;
|
||||||
@@ -36,26 +35,35 @@ async fn handle_connection(mut socket: tokio::net::TcpStream, real_power_socket:
|
|||||||
match buf {
|
match buf {
|
||||||
[CMD_GET_ON] => {
|
[CMD_GET_ON] => {
|
||||||
println!("handling CMD_GET_ON");
|
println!("handling CMD_GET_ON");
|
||||||
let power_socket = real_power_socket.try_read().map_err(|e| std::io::Error::other(e))?;
|
{
|
||||||
|
let power_socket = real_power_socket.try_read().map_err(|_| std::io::Error::other("read lock failed"))?;
|
||||||
buf = if power_socket.on { [1u8; 1] } else { [0u8; 1] };
|
buf = if power_socket.on { [1u8; 1] } else { [0u8; 1] };
|
||||||
|
}
|
||||||
let _ = tokio::time::timeout(TIMEOUT, socket.write(&buf)).await?;
|
let _ = tokio::time::timeout(TIMEOUT, socket.write(&buf)).await?;
|
||||||
}
|
}
|
||||||
[CMD_TURN_ON] => {
|
[CMD_TURN_ON] => {
|
||||||
println!("handling CMD_TURN_ON");
|
println!("handling CMD_TURN_ON");
|
||||||
let mut power_socket = real_power_socket.try_write().map_err(|e| std::io::Error::other(e))?;
|
{
|
||||||
|
let mut power_socket = real_power_socket.try_write().map_err(|_| std::io::Error::other("write lock failed"))?;
|
||||||
power_socket.on = true;
|
power_socket.on = true;
|
||||||
|
}
|
||||||
let _ = tokio::time::timeout(TIMEOUT, socket.write(&buf)).await?;
|
let _ = tokio::time::timeout(TIMEOUT, socket.write(&buf)).await?;
|
||||||
}
|
}
|
||||||
[CMD_TURN_OFF] => {
|
[CMD_TURN_OFF] => {
|
||||||
println!("handling CMD_TURN_OFF");
|
println!("handling CMD_TURN_OFF");
|
||||||
let mut power_socket = real_power_socket.try_write().map_err(|e| std::io::Error::other(e))?;
|
{
|
||||||
|
let mut power_socket = real_power_socket.try_write().map_err(|_| std::io::Error::other("write lock failed"))?;
|
||||||
power_socket.on = false;
|
power_socket.on = false;
|
||||||
|
}
|
||||||
let _ = tokio::time::timeout(TIMEOUT, socket.write(&buf)).await?;
|
let _ = tokio::time::timeout(TIMEOUT, socket.write(&buf)).await?;
|
||||||
}
|
}
|
||||||
[CMD_GET_POWER] => {
|
[CMD_GET_POWER] => {
|
||||||
println!("handling CMD_GET_POWER");
|
println!("handling CMD_GET_POWER");
|
||||||
let power_socket = real_power_socket.try_read().map_err(|e| std::io::Error::other(e))?;
|
let data_buf: [u8; 4];
|
||||||
let data_buf = power_socket.power_rate.to_le_bytes();
|
{
|
||||||
|
let power_socket = real_power_socket.try_read().map_err(|_| std::io::Error::other("read lock failed"))?;
|
||||||
|
data_buf = power_socket.power_rate.to_le_bytes();
|
||||||
|
}
|
||||||
let _ = tokio::time::timeout(TIMEOUT, socket.write(&data_buf)).await?;
|
let _ = tokio::time::timeout(TIMEOUT, socket.write(&data_buf)).await?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -66,7 +74,7 @@ async fn handle_connection(mut socket: tokio::net::TcpStream, real_power_socket:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let real_power_socket = Arc::new(tokio::sync::RwLock::new(RealPowerSocket { power_rate: 12.0, on: false }));
|
let real_power_socket = Arc::new(RwLock::new(RealPowerSocket { power_rate: 12.0, on: false }));
|
||||||
let rt = tokio::runtime::Builder::new_current_thread().enable_all().build()?;
|
let rt = tokio::runtime::Builder::new_current_thread().enable_all().build()?;
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let listener = tokio::net::TcpListener::bind(parse_args()).await?;
|
let listener = tokio::net::TcpListener::bind(parse_args()).await?;
|
||||||
|
|||||||
@@ -1,10 +1 @@
|
|||||||
use smart_house::PowerSocket;
|
fn main() {}
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut power_socket = PowerSocket::connect("127.0.0.1:10001");
|
|
||||||
println!("{}", power_socket.display());
|
|
||||||
std::thread::sleep(Duration::from_secs(2));
|
|
||||||
power_socket.set_on(!power_socket.is_on());
|
|
||||||
println!("{}", power_socket.display());
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user