Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenifer-TheCoder authored Jun 30, 2024
1 parent f0a5fc4 commit c510f61
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "chat_app"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = { version = "1", features = ["full"] }
tokio-tungstenite = "0.15"
tungstenite = "0.16"
futures-util = "0.3"
url = "2.2"
warp = "0.3"

[[bin]]
name = "server"
path = "src/server.rs"

[[bin]]
name = "client"
path = "src/client.rs"
105 changes: 105 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat App</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f4f4f4;
}
#chatContainer {
width: 100%;
max-width: 600px;
height: 80%;
display: flex;
flex-direction: column;
border: 1px solid #ccc;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #fff;
}
#chat {
flex: 1;
padding: 10px;
overflow-y: auto;
background-color: #f9f9f9;
}
#messageInput {
display: flex;
padding: 10px;
background-color: #fff;
border-top: 1px solid #ccc;
}
#messageInput input, #messageInput button {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
#messageInput input {
flex: 1;
margin-right: 10px;
}
#messageInput button {
background-color: #4CAF50;
color: white;
cursor: pointer;
border-left: none;
}
.message {
padding: 10px;
margin: 10px 0;
border-radius: 10px;
background-color: #e1f5fe;
word-wrap: break-word;
}
.message span {
font-weight: bold;
color: #00796b;
}
</style>
</head>
<body>
<div id="chatContainer">
<div id="chat"></div>
<div id="messageInput">
<input type="text" id="username" placeholder="Enter your name" autocomplete="off">
<input type="text" id="message" placeholder="Type your message here..." autocomplete="off">
<button onclick="sendMessage()">Send</button>
</div>
</div>

<script>
let ws = new WebSocket("ws://127.0.0.1:8080/ws");

ws.onmessage = function(event) {
let chat = document.getElementById("chat");
let message = document.createElement("div");
message.className = "message";
message.textContent = event.data;
chat.appendChild(message);
chat.scrollTop = chat.scrollHeight;
};

function sendMessage() {
let usernameInput = document.getElementById("username");
let messageInput = document.getElementById("message");
if (usernameInput.value && messageInput.value) {
let message = usernameInput.value + ": " + messageInput.value;
ws.send(message);
messageInput.value = '';
} else {
alert("Please enter both your name and a message.");
}
}
</script>
</body>
</html>
61 changes: 61 additions & 0 deletions server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use tokio::net::TcpListener;
use tokio_tungstenite::accept_async;
use tokio_tungstenite::tungstenite::protocol::Message;
use futures_util::{StreamExt, SinkExt};
use std::sync::{Arc, Mutex};
use tokio::sync::broadcast;
use warp::Filter;
use warp::fs::File;
use std::convert::Infallible;
#[tokio::main]
async fn main() {
// Set up the broadcast channel
let (tx, _rx) = broadcast::channel(100);
let tx = Arc::new(Mutex::new(tx));
// WebSocket handler
let tx_ws = tx.clone();
let ws_route = warp::path("ws")
.and(warp::ws())
.map(move |ws: warp::ws::Ws| {
let tx = tx_ws.clone();
ws.on_upgrade(move |websocket| handle_connection(websocket, tx))
});
// Static file handler
let static_route = warp::path::end()
.and(warp::fs::file("static/index.html"));
// Combine routes
let routes = ws_route.or(static_route);
println!("Server listening on 127.0.0.1:8080");
// Start the server
warp::serve(routes)
.run(([127, 0, 0, 1], 8080))
.await;
}
async fn handle_connection(ws: warp::ws::WebSocket, tx: Arc<Mutex<broadcast::Sender<String>>>) {
let (mut ws_sender, mut ws_receiver) = ws.split();
// Subscribe to the broadcast channel
let mut rx = tx.lock().unwrap().subscribe();
// Task to send broadcast messages to the client
tokio::spawn(async move {
while let Ok(msg) = rx.recv().await {
if ws_sender.send(warp::ws::Message::text(msg)).await.is_err() {
break;
}
}
});
// Process incoming messages
while let Some(result) = ws_receiver.next().await {
match result {
Ok(message) => {
if let Ok(text) = message.to_str() {
println!("Received message: {}", text);
tx.lock().unwrap().send(text.to_string()).expect("Failed to broadcast message");
}
},
Err(e) => {
eprintln!("Error receiving message: {}", e);
break;
}
}
}
}

0 comments on commit c510f61

Please sign in to comment.