Start to create WS client for cli_player
This commit is contained in:
@ -17,4 +17,8 @@ tokio = "1.21.2"
|
||||
num = "0.4.0"
|
||||
num-traits = "0.2.15"
|
||||
num-derive = "0.3.3"
|
||||
textwrap = "0.15.1"
|
||||
textwrap = "0.15.1"
|
||||
tokio-tungstenite = "0.17.2"
|
||||
serde_urlencoded = "0.7.1"
|
||||
futures = "0.3.23"
|
||||
serde_json = "1.0.85"
|
@ -41,6 +41,11 @@ impl CliArgs {
|
||||
.parse::<u16>()
|
||||
.expect("Failed to parse listen port!")
|
||||
}
|
||||
|
||||
/// Get local server address
|
||||
pub fn local_server_address(&self) -> String {
|
||||
format!("http://localhost:{}", self.listen_port())
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
|
95
rust/cli_player/src/client.rs
Normal file
95
rust/cli_player/src/client.rs
Normal file
@ -0,0 +1,95 @@
|
||||
use crate::cli_args::cli_args;
|
||||
use crate::server;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use sea_battle_backend::data::GameRules;
|
||||
use sea_battle_backend::human_player_ws::{ClientMessage, ServerMessage};
|
||||
use sea_battle_backend::server::BotPlayQuery;
|
||||
use sea_battle_backend::utils::{boxed_error, Res};
|
||||
use tokio::net::TcpStream;
|
||||
use tokio_tungstenite::tungstenite::Message;
|
||||
use tokio_tungstenite::{MaybeTlsStream, WebSocketStream};
|
||||
|
||||
/// Connection client
|
||||
///
|
||||
/// This structure acts as a wrapper around websocket connection that handles automatically parsing
|
||||
/// of incoming messages and encoding of outgoing messages
|
||||
pub struct Client {
|
||||
socket: WebSocketStream<MaybeTlsStream<TcpStream>>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Start to play against a bot
|
||||
///
|
||||
/// When playing against a bot, local server is always used
|
||||
pub async fn start_bot_play(rules: &GameRules) -> Res<Self> {
|
||||
server::start_server_if_missing().await;
|
||||
|
||||
Self::connect_url(
|
||||
&cli_args().local_server_address(),
|
||||
&format!(
|
||||
"/play/bot?{}",
|
||||
serde_urlencoded::to_string(&BotPlayQuery {
|
||||
rules: rules.clone(),
|
||||
player_name: "Human".to_string()
|
||||
})
|
||||
.unwrap()
|
||||
),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Do connect to a server, returning
|
||||
async fn connect_url(server: &str, uri: &str) -> Res<Self> {
|
||||
let mut url = server.replace("http", "ws");
|
||||
url.push_str(uri);
|
||||
log::debug!("Connecting to {}", url);
|
||||
|
||||
let (socket, _) = tokio_tungstenite::connect_async(url).await?;
|
||||
|
||||
Ok(Self { socket })
|
||||
}
|
||||
|
||||
/// Receive next message from stream
|
||||
async fn recv_next_msg(&mut self) -> Res<ServerMessage> {
|
||||
loop {
|
||||
let chunk = match self.socket.next().await {
|
||||
None => return Err(boxed_error("No more message in queue!")),
|
||||
Some(d) => d,
|
||||
};
|
||||
|
||||
match chunk? {
|
||||
Message::Text(t) => {
|
||||
log::debug!("TEXT Got a text message from server!");
|
||||
let msg: ServerMessage = serde_json::from_str(&t)?;
|
||||
return Ok(msg);
|
||||
}
|
||||
Message::Binary(_) => {
|
||||
log::debug!("BINARY Got an unexpected binary message");
|
||||
return Err(boxed_error("Received an unexpected binary message!"));
|
||||
}
|
||||
Message::Ping(_) => {
|
||||
log::debug!("PING Got a ping message from server");
|
||||
}
|
||||
Message::Pong(_) => {
|
||||
log::debug!("PONG Got a pong message");
|
||||
}
|
||||
Message::Close(_) => {
|
||||
log::debug!("CLOSE Got a close websocket message");
|
||||
return Err(boxed_error("Server requested to close connection!"));
|
||||
}
|
||||
Message::Frame(_) => {
|
||||
log::debug!("FRAME Got an unexpected frame from server!");
|
||||
return Err(boxed_error("Got an unexpected frame!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a message through the stream
|
||||
pub async fn send_message(&mut self, msg: &ClientMessage) -> Res {
|
||||
self.socket
|
||||
.send(Message::Text(serde_json::to_string(&msg)?))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
pub mod cli_args;
|
||||
pub mod client;
|
||||
pub mod constants;
|
||||
pub mod server;
|
||||
pub mod ui_screens;
|
||||
|
Reference in New Issue
Block a user