vesys-bank-server/socket-server/src/server.rs

65 lines
1.4 KiB
Rust

use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, RwLock};
use anyhow::{bail, Result};
use bank::bank::Bank;
use crate::commands::Commands;
use crate::protocol;
use crate::threadpool::ThreadPool;
pub fn run(host: &str, threads: usize) -> Result<()> {
let listener = TcpListener::bind(host)?;
let pool = ThreadPool::new(threads);
let cmds = Arc::new(Commands::new());
let bank = Arc::new(RwLock::new(Bank::new()));
for stream in listener.incoming() {
let cmds = cmds.clone();
let bank = bank.clone();
let stream = stream?;
pool.execute(move || {
if let Err(e) = handle_connection(bank, &cmds, stream) {
error!("{}", e);
}
});
}
Ok(())
}
fn handle_connection(
bank: Arc<RwLock<Bank>>,
cmds: &Commands,
mut stream: TcpStream,
) -> Result<()> {
const BUF_SIZE: usize = 64;
let mut data: Vec<u8> = vec![];
let mut buffer = [0; BUF_SIZE];
let mut read = stream.read(&mut buffer)?;
while read > 0 {
data.append(&mut buffer[..read].to_vec());
read = stream.read(&mut buffer)?;
}
if data[..2] != protocol::START {
bail!("got {:?} as first bytes, not my problem", &data[..2]);
}
let cmd: u8 = (data[2] & 0b1111_0000) >> 4;
trace!("got command {}", cmd);
cmds.run(bank, cmd, &data[3..], &stream)?;
stream.flush()?;
Ok(())
}