Skip to content

GreenJ84/Rustic_Mesaging

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

109 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rustic Messaging System

Real-time messaging system built in Rust with a focus on authentication, secure communication, connection management, and low-latency.

Tech: Rust • Yew • WebSockets • JWT • Redis • Nginx • YugabyteDB

📌 Overview

The app is split into a Yew frontend, a Rocket-based API, and a YugabyteDB-backed data layer. The current setup also includes helper crates for local startup and test startup, so the same services can be brought up in different ways without duplicating the core app logic.

🏗️ Architecture

  • The Yew client talks to the API for normal requests and uses WebSockets for real-time message delivery
  • Authentication is handled with JWTs during request and connection setup
  • The server validates token claims, expiration, and signature before granting access
  • Messages are routed through active connection handlers rather than polling loops
  • Connection and session state is kept intentionally simple so it can later move toward shared infrastructure

The system separates authentication, connection handling, message routing, and persistence so each concern can evolve independently.

🔐 Authentication Flow

  • User authenticates and receives a JWT
  • The token is attached to subsequent authenticated requests and WebSocket initialization
  • The server checks expiration, signature, and claims before accepting the session
  • Valid sessions are tied to the user identity that was encoded in the token
  • Expired or invalid tokens are rejected early so unauthorized connections never reach the chat flow

Token lifecycle handling includes expiration checks and session validation to ensure secure communication channels.

⚡ Real-Time Communication

  • WebSocket-based persistent connections for low-latency delivery
  • Connection lifecycle management for connect, message, and disconnect events
  • Structured message handling so messages can be validated and routed consistently
  • A client/server split that keeps the browser UI light and the server responsible for shared state

The system prioritizes efficient message routing, connection stability, and a UI that can stay responsive while the server handles the real-time work.

📈 Performance Considerations

  • Designed to minimize connection overhead and avoid unnecessary polling
  • Built to handle multiple concurrent WebSocket sessions efficiently
  • Planned Redis integration for caching, fan-out, and shared session state
  • Separation of state makes it easier to scale the backend horizontally later

🧱 Scaling Strategy (Planned)

  • Redis will be implemented for pub/sub messaging and shared session state across nodes (Required to support horizontal scaling of WebSocket connections)
  • Support horizontal scaling of WebSocket servers when traffic grows
  • Decouple the messaging layer for a more event-driven architecture later

The current implementation has connection state currently maintained in-memory per node, which simplifies development but limits horizontal scalability, planned implementation of Redis for shared state infrastructure will address this limitation.

🐳 Dockerization

The repository is already structured for containerized development. The backend and frontend each have their own Dockerfile, and the root compose file ties them together with YugabyteDB so the production-like stack can be reproduced locally.

  • The server image uses a multi-stage Rust build so the compiled API binary can be copied into a smaller runtime image.
  • The runtime server container exposes port 8000 and listens on 0.0.0.0 so other containers can reach it.
  • The client image builds the Yew app with Trunk and serves the generated static files through Nginx.
  • The client container exposes port 80, which becomes the browser entry point in Compose.
  • Nginx proxies /api requests to the server container so the frontend and API behave like a single site from the browser's point of view.

This setup keeps build tooling inside the image, keeps runtime images focused on serving the app, and makes the same stack easier to run in a deployment pipeline or on another machine.

🧩 Compose Setup

The compose file wires the three services together: yugabyte, server, and client. Each service has a narrow responsibility so the stack is easy to reason about and the startup order stays predictable.

  • yugabyte provides the PostgreSQL-compatible database port used by Diesel and the Rust server.
  • server waits for YugabyteDB to become ready, resets the schema, runs migrations, and then launches the API.
  • client is built from the frontend Dockerfile and served by Nginx on host port 80.
  • The server attaches to both the frontend and backend networks so it can reach the database and accept requests from the Nginx container.
  • The database uses a bind-mounted data directory so local state persists across container restarts.

The compose layout is intentionally simple: one service for persistence, one for the API, and one for the browser-facing frontend. That makes startup order, port mapping, and debugging much easier while still matching the shape of the app in production.

▶️ Running the Project

There are 2 ways to run the project:

  • *local environment*: starting each service individually for local development
  • *Docker environment*: starting the full stack through Docker Compose in a production-like environment

Each approach has its own use case and setup requirements.

Repository Setup

These setup steps are shared by both workflows.

  1. Clone the repository.
  2. Open the workspace root so the helper crates can be run from a single terminal context.
  3. Install Docker (and Docker Compose if you want to run the compose stack).
  4. Create the local server environment settings from .env templates: server/.env.template and server/.env.prod.template and fill in according to template instructions.
git clone https://github.com/GreenJ84/Rustic_Mesaging.git #1
cd Rustic_Mesaging #2

curl  -fsSL https://get.docker.com  | sh #3

mv server/.env.template server/.env #4
mv server/.env.prod.template server/.env.prod #4

Local Environment

This path uses a custom package to bring up the database, reset the schema, launch the API, and serve the frontend.

  1. Install Rust and Cargo with rustup; if not already installed
  2. Install Trunk and the Diesel CLI; if not already installed
  3. Make sure Docker is running, because the startup package creates a YugabyteDB container before running tests.
  4. From the workspace root, start the local development helper package, app_startup.
  5. Wait for YugabyteDB to start, the schema to reset, and the API to launch.
  6. Open the API at http://localhost:8000.
  7. Open the frontend at http://localhost:3000.
rustup toolchain install stable #1
rustup default stable #1

cargo install trunk #2
cargo install diesel_cli --no-default-features --features postgres #2

docker info #3 - Should not have an error connecting to the Docker daemon

cargo run -p app_startup #4

Docker Compose Environment

This path starts the database, API server, and Nginx-served frontend together as one stack.

  1. From the repository root, build and start the compose stack.
  2. Wait for YugabyteDB, the API container, and the Nginx client container to start.
  3. Open http://localhost in your browser.
  4. Use docker compose down when you want to stop the stack.
docker compose up --build

docker compose down

🪪 License

This project is licensed under the MIT License - see the LICENSE.md file for details.

The MIT License is a permissive license that allows users to use, copy, modify, merge, publish, distribute, and sublicense the software, provided that they include the original copyright notice and disclaimer. It also provides an implied warranty of fitness for a particular purpose and limits the liability of the software's authors and contributors.

By using or contributing to this project, you agree to be bound by the terms and conditions of the MIT License.

If you have any questions about the license or would like to use this software under a different license, please contact the project maintainers.

🤗 Contributing

Contributions are welcome!

Please refer to my profile Code of Conduct before contributing to this project.

My Contribution Guide has more details on how to get started contributing.

Feel free to open an issue or submit a pull request if you have a way to improve this project.

Make sure your request is meaningful, thought out, and that you have tested the app locally before submitting a pull request.

🙋‍♂️ Support

💙 If you like this project, give it a ⭐ and share it with friends!

Sponsor with Github


Made with Rust, Yew, Rocket, Redis, YugabyteDB, and ❤️‍🔥

About

Rustic Messaging is a real-time chat application designed to bring people together effortlessly. Whether you're joining vibrant chat rooms, sending private messages, or managing your favorite servers, Rustic Messaging ensures smooth and secure communication.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages