Compare commits
2 commits
88aacacb19
...
886c2efe5d
Author | SHA1 | Date | |
---|---|---|---|
|
886c2efe5d | ||
|
c14f3c4558 |
5 changed files with 89 additions and 35 deletions
5
src/client/events.rs
Normal file
5
src/client/events.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum ChatAppEvent {
|
||||||
|
ConnectButtonPress,
|
||||||
|
HostTextInputChanged(String)
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
mod websocket;
|
mod websocket;
|
||||||
|
mod events;
|
||||||
|
|
||||||
use iced::widget::{column, Column, button, text_input, text};
|
use iced::widget::{column, Column, button, text_input, text};
|
||||||
use iced::{Application, Command, Element, Pixels, settings::Settings};
|
use iced::{Application, Command, Element, Pixels, settings::Settings};
|
||||||
use iced_futures::Subscription;
|
use iced_futures::Subscription;
|
||||||
use websocket::websocket;
|
use websocket::{websocket, AppWebsocketConfig};
|
||||||
use crate::websocket::AppWebsocketConfig;
|
use events::ChatAppEvent;
|
||||||
|
|
||||||
fn main() -> iced::Result {
|
fn main() -> iced::Result {
|
||||||
let settings = Settings {
|
let settings = Settings {
|
||||||
|
@ -25,12 +26,6 @@ struct ChatApp {
|
||||||
host: String
|
host: String
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
enum ChatAppEvent {
|
|
||||||
ConnectButtonPress,
|
|
||||||
HostTextInputChanged(String)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChatApp {
|
impl ChatApp {
|
||||||
fn view_auth(&self) -> Element<<ChatApp as Application>::Message> {
|
fn view_auth(&self) -> Element<<ChatApp as Application>::Message> {
|
||||||
column![
|
column![
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
use futures_util::stream::{SplitSink, SplitStream};
|
||||||
|
use futures_util::StreamExt;
|
||||||
use iced::subscription::{Subscription, channel};
|
use iced::subscription::{Subscription, channel};
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream};
|
||||||
|
use crate::events::ChatAppEvent;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub enum AppWebsocketState {
|
pub enum AppWebsocketState {
|
||||||
Disconnected,
|
Disconnected,
|
||||||
Connected
|
Error(String),
|
||||||
|
Connected(SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, tokio_tungstenite::tungstenite::Message>, SplitStream<WebSocketStream<MaybeTlsStream<TcpStream>>>)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
@ -23,7 +29,7 @@ impl AppWebsocketConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn websocket(config: AppWebsocketConfig) -> Subscription<super::ChatAppEvent> {
|
pub fn websocket(config: AppWebsocketConfig) -> Subscription<ChatAppEvent> {
|
||||||
struct Websocket;
|
struct Websocket;
|
||||||
|
|
||||||
channel(
|
channel(
|
||||||
|
@ -33,7 +39,21 @@ pub fn websocket(config: AppWebsocketConfig) -> Subscription<super::ChatAppEvent
|
||||||
let mut state = AppWebsocketState::Disconnected;
|
let mut state = AppWebsocketState::Disconnected;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
match &state {
|
||||||
|
AppWebsocketState::Disconnected => {
|
||||||
|
match connect_async(&config.host).await {
|
||||||
|
Ok((conn, res)) => {
|
||||||
|
let (ws_recv, ws_send) = conn.split();
|
||||||
|
state = AppWebsocketState::Connected(ws_recv, ws_send);
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
state = AppWebsocketState::Error(err.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AppWebsocketState::Connected(ws_recv, ws_send) => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
Text { chat: (), content: String }
|
Text { chat: (), content: String }
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{net::SocketAddr, sync::Arc};
|
||||||
use tokio::{net::{TcpListener, TcpStream}, sync::Mutex};
|
use tokio::{net::{TcpListener, TcpStream}, sync::Mutex};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use figment::{Figment, providers::{Format, Env, Json}};
|
use figment::{Figment, providers::{Format, Env, Json}};
|
||||||
use futures_util::{StreamExt, stream::SplitSink, TryStreamExt, };
|
use futures_util::{StreamExt, stream::SplitSink, TryStreamExt, SinkExt};
|
||||||
use tokio_tungstenite::{WebSocketStream, tungstenite::Message as TungsteniteMessage};
|
use tokio_tungstenite::{WebSocketStream, tungstenite::Message as TungsteniteMessage};
|
||||||
use common::packets::Message;
|
use common::packets::Message;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ async fn handle_connection(stream: TcpStream, addr: SocketAddr, peer_list: PeerL
|
||||||
.await
|
.await
|
||||||
.expect("Could not initialize websocket stream");
|
.expect("Could not initialize websocket stream");
|
||||||
|
|
||||||
let (mut websocket_tx, mut websocket_rx) = websocket_stream.split();
|
let (websocket_tx, mut websocket_rx) = websocket_stream.split();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut locked_peer_list = peer_list.lock().await;
|
let mut locked_peer_list = peer_list.lock().await;
|
||||||
|
@ -59,22 +59,7 @@ async fn handle_connection(stream: TcpStream, addr: SocketAddr, peer_list: PeerL
|
||||||
while let Some(socket_result) = websocket_rx.next().await {
|
while let Some(socket_result) = websocket_rx.next().await {
|
||||||
match socket_result {
|
match socket_result {
|
||||||
Ok(websocket_message) => {
|
Ok(websocket_message) => {
|
||||||
match websocket_message {
|
handle_websocket_message(websocket_message, addr, peer_list.clone()).await;
|
||||||
TungsteniteMessage::Text(text_message) => {
|
|
||||||
match serde_json::from_str(&text_message) {
|
|
||||||
Ok(message) => {
|
|
||||||
handle_message(message, addr, peer_list.clone())
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("ParseError: {err}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
println!("Websocket: Unsupported message type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("SocketError: {err}");
|
eprintln!("SocketError: {err}");
|
||||||
|
@ -84,10 +69,56 @@ async fn handle_connection(stream: TcpStream, addr: SocketAddr, peer_list: PeerL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_message(message: Message, sender: SocketAddr, peer_list: PeerList) {
|
async fn handle_websocket_message(websocket_message: TungsteniteMessage, addr: SocketAddr, peer_list: PeerList) {
|
||||||
match message {
|
match websocket_message {
|
||||||
Message::Text { chat, content} => {
|
TungsteniteMessage::Text(text_message) => {
|
||||||
println!("{chat}: {content}")
|
match serde_json::from_str(&text_message) {
|
||||||
|
Ok(message) => {
|
||||||
|
if let Err(err) = handle_message(message, addr, peer_list.clone()).await {
|
||||||
|
eprintln!("Handle message error: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("ParseError: {err}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TungsteniteMessage::Close(_) => {
|
||||||
|
let mut locked_peer_list = peer_list.lock().await;
|
||||||
|
|
||||||
|
for i in 0..locked_peer_list.len() {
|
||||||
|
if locked_peer_list[i].addr.to_string() == addr.to_string() {
|
||||||
|
locked_peer_list.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Websocket: Unsupported message type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn handle_message(message: Message, sender: SocketAddr, peer_list: PeerList) -> anyhow::Result<()> {
|
||||||
|
match &message {
|
||||||
|
Message::Text { chat, content} => {
|
||||||
|
let mut use_peer_list = peer_list.lock().await;
|
||||||
|
|
||||||
|
for mut peer in &mut *use_peer_list {
|
||||||
|
println!("[Message]{}: {content}", peer.addr.to_string());
|
||||||
|
if peer.addr.to_string() == sender.to_string() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
peer.websocket_tx.send(
|
||||||
|
tokio_tungstenite::tungstenite::Message::Text(
|
||||||
|
serde_json::to_string(&message)?
|
||||||
|
)
|
||||||
|
).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
Loading…
Reference in a new issue