use std::{
error::Error
};
use log::{warn};
use env_logger::Env;
use async_std::{
task,
io::{
BufReader,
BufWriter,
},
net::{
TcpListener,
},
};
use futures::{
prelude::*,
AsyncRead,
AsyncWrite,
};
use oc_http::websocket::{
self,
WebSocketReader,
WebSocketWriter,
WebSocketError,
};
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
let listener = TcpListener::bind("127.0.0.1:8080").await?;
let _local_addr = listener.local_addr()?;
let mut incoming = listener.incoming();
while let Some(stream) = incoming.next().await {
if let Ok(stream) = stream {
task::spawn(handle_request(stream));
}
}
Ok(())
}
async fn handle_request<S>(stream: S)
where S: AsyncRead + AsyncWrite + Clone + Unpin
{
let mut reader = BufReader::new(stream.clone());
let request = match oc_http::http(&mut reader).await {
Ok(req) => req,
Err(err) => {
warn!("Error {}", err);
return;
},
};
if request.path == "/ws" && request.method == "GET" {
let ws = websocket::upgrade(&request, stream).await.unwrap();
handle_websocket(ws.0, ws.1).await;
} else {
let mut writer = BufWriter::new(stream);
oc_http::respond(&mut writer, oc_http::Response{
code: 404,
reason: "NOT FOUND",
headers: vec!(),
}).await.unwrap();
writer.flush().await.unwrap();
}
}
async fn handle_websocket<S>(mut rdr: WebSocketReader<S>, mut wrt: WebSocketWriter<S>)
where S: AsyncRead + AsyncWrite + Clone + Unpin {
loop {
let msg = match rdr.recv().await {
Ok(msg) => msg,
Err(WebSocketError::ConnectionClosed) => return,
Err(err) => {
warn!("Sadness is {:?}", err);
return
},
};
wrt.write(&msg).await.unwrap();
}
}