This commit is contained in:
2025-06-05 21:20:52 +02:00
commit 2a55ba5fc9
7 changed files with 2436 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/target
app/

2321
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

14
Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "chat-app"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0.98"
axum = { version = "0.8.4", features = ["multipart", "ws"] }
futures-util = "0.3.31"
serde = { version = "1.0.219", features = ["derive"] }
tokio = { version = "1.45.1", features = ["full"] }
axum-valid = { path = "../axum-valid", features = ["basic", "typed_multipart", "validify"], default-features = false }
validify = "2.0.0"
axum_typed_multipart = "0.16.2"

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
Frontend: SvelteKit, shadcn-svelte
Backend: axum, tokio, Websockets, sqlx, serde

28
src/main.rs Normal file
View File

@@ -0,0 +1,28 @@
mod send_message_handler;
mod websockets;
use std::sync::Arc;
use axum::{
Router,
routing::{get, post},
};
use tokio::{net::TcpListener, sync::Mutex};
pub type MyState = Arc<Mutex<Vec<String>>>;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let state = MyState::default();
let router: Router = Router::new()
.route("/message", post(send_message_handler::handler))
.route("/ws", get(websockets::websocket_handler))
.with_state(state);
let listener = TcpListener::bind("127.0.0.1:3000").await?;
let _ = axum::serve(listener, router).await;
Ok(())
}

View File

@@ -0,0 +1,27 @@
use axum::{extract::State, http::StatusCode};
use axum_typed_multipart::{TryFromMultipart, TypedMultipart};
use axum_valid::ValidifiedByRef;
use validify::Validify;
use crate::MyState;
#[derive(Validify, TryFromMultipart)]
pub struct SendMessageData {
#[modify(trim)]
content: String,
}
pub async fn handler(
State(state): State<MyState>,
ValidifiedByRef(TypedMultipart(data)): ValidifiedByRef<TypedMultipart<SendMessageData>>,
) -> StatusCode {
let mut messages = state.lock().await;
// println!("{}", &data.content);
messages.push(data.content);
dbg!(&messages);
StatusCode::OK
}

42
src/websockets.rs Normal file
View File

@@ -0,0 +1,42 @@
use std::time::Duration;
use axum::{
extract::{
WebSocketUpgrade,
ws::{Message, WebSocket},
},
response::Response,
};
use futures_util::{
SinkExt as _, StreamExt,
stream::{SplitSink, SplitStream},
};
pub async fn websocket_handler(upgrade: WebSocketUpgrade) -> Response {
upgrade.on_upgrade(handler)
}
async fn handler(socket: WebSocket) {
let (sender, receiver) = socket.split();
tokio::spawn(receive(receiver));
tokio::spawn(send(sender));
}
async fn send(mut sender: SplitSink<WebSocket, Message>) {
loop {
let _ = sender.send("Hello client!".into());
tokio::time::sleep(Duration::from_secs(5)).await;
}
}
async fn receive(mut stream: SplitStream<WebSocket>) {
while let Some(Ok(message)) = stream.next().await {
let Ok(text) = message.to_text() else {
continue;
};
println!("Message: {text}");
}
}