Skip to content

Fab-Ver/rust-text-chat-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ’¬Ruggine – Text Chat Application

πŸš€ Overview

Project for the course "System Programming" of the Master's Degree in Computer Engineering at the Polytechnic University of Turin.

The contributors are:

  1. Fabio Veroli - GitHub
  2. Ivan Necerini - GitHub
  3. Jacopo Rialti - GitHub
  4. Dario Lupo - GitHub

Ruggine is a cross-platform chat application written entirely in Rust, featuring:

  • A multi-threaded TCP server managing client connections.
  • A desktop GUI client using the iced crate
  • A shared protocol for communication between client and server
  • A SQLite database for users, groups, messages, and invitations

πŸ’‘ Scroll all down to see the GUI screenshots!


🏁 Getting Started

To get a local copy up and running, follow these simple steps.

Prerequisites

  • Rust
  • SQLite

Installation

  1. Clone the repo
    git clone <repository-url>
  2. Build the project
    cargo build
  3. Initialize the database
    sqlite3 server/database/ruggine.db < server/database/init.sql

    Note: Make sure you have SQLite3 installed on your system. If the database file already exists, you can skip this step.

  4. Run the server
    cargo run --bin server
  5. Run one or more instances of the client and try it out
    cargo run --bin client

πŸ—‚οΈ Project Structure

ruggine/
β”œβ”€β”€ client/
β”‚   β”œβ”€β”€ src/
|   β”‚   β”œβ”€β”€ communication/
|   β”‚   β”‚   β”œβ”€β”€ mod.rs
|   β”‚   β”‚   └── server_communication.rs
|   β”‚   β”œβ”€β”€ update/
|   β”‚   β”‚   β”œβ”€β”€ mod.rs
|   β”‚   β”‚   β”œβ”€β”€ update_commands.rs
|   β”‚   β”‚   └── update_handlers.rs
|   β”‚   β”œβ”€β”€ view/
|   β”‚   β”‚   β”œβ”€β”€ mod.rs
|   β”‚   β”‚   β”œβ”€β”€ ui.rs
|   β”‚   β”‚   β”œβ”€β”€ util_ui.rs
|   β”‚   β”‚   └── gui_messages.rs
|   β”‚   β”œβ”€β”€ main.rs
|   β”‚   └── app_states.rs  
β”‚   └── Cargo.toml
β”œβ”€β”€ server/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ main.rs
β”‚   β”‚   β”œβ”€β”€ handler.rs
β”‚   β”‚   β”œβ”€β”€ logger.rs
β”‚   β”‚   β”œβ”€β”€ utils.rs
β”‚   β”‚   └── database_management.rs
β”‚   β”œβ”€β”€ database/
β”‚   β”‚   β”œβ”€β”€ init.sql
β”‚   β”‚   └── ruggine.db
β”‚   β”œβ”€β”€ log/
β”‚   β”‚   └── cpu_log.txt
β”‚   └── Cargo.toml
β”‚
β”œβ”€β”€ protocol/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs
β”‚   β”‚   β”œβ”€β”€ message.rs
β”‚   β”‚   β”œβ”€β”€ data_structures.rs
β”‚   └── Cargo.toml
β”‚
└── Cargo.toml (workspace)

✨ Features

  • User authentication with auto-registration for new users
  • Direct messaging between users:
    • One-to-one chat
    • Message history
    • Unread message notifications
  • Group chat with:
    • Real-time messaging
    • Member management, owner can add/remove members
    • Invitations
    • Group history
    • Unread message notifications
  • Unread messages indicator and auto-update on message receipt
  • Desktop GUI:
    • Welcome/Login
    • Group and direct chat lists
    • Invitation management
    • Group management (owner can remove users or delete the group)
    • Direct chat management (search users, start new chats)
  • Logging:
    • CPU usage logged every 2 minutes
    • Messages stored in SQLite
  • Error handling:
    • Informative error messages on failed actions (e.g., wrong password, user not found, connection issues...), including server-side and client-side handling

🧩 Modules Overview

🎯 Client Module

The client is responsible for handling the user interface (UI) and communication with the server.

πŸ“¦ communication/ - Server Communication

The communication module is responsible for managing asynchronous communication between the client and the server. It leverages the protocol crate to serialize messages and handle communication over TCP.

  • server_communication.rs: Contains functions for sending and receiving messages between the client and the server. Asynchronous functions are defined to send Message variants (such as login credentials, chat messages, and group invitations) and process server responses.

πŸ“¦ update/ - Update Logic

The update module manages state transitions and interactions between the client and the server.

  • update_commands.rs: Contains commands that trigger asynchronous actions, calling functions defined in server_communication.rs to communicate with the server. It handles network-related commands such as login, sending messages, or requesting user chats.

  • update_handlers.rs: Defines the logic for each application state (ViewState). It contains handlers that manage incoming messages and update the client’s state based on the message type. For example, when the server sends a new chat message, the handler updates the UI to display it, and when an error occurs, it triggers the error display logic.

πŸ“¦ view/ - User Interface

The view module is responsible for building the GUI components and rendering the UI based on the current application state.

  • gui_messages.rs: Defines all the messages that are generated by the view and passed to the update function. These messages are used to reflect changes in the application’s state (like switching from login to chat view).

  • ui.rs: Contains the functions that define the layout and structure of the user interface for each ViewState. For each state (e.g., Username, Chats), there is a corresponding function to render the UI components dynamically.

  • util_ui.rs: Defines custom UI elements like buttons, containers, and input fields. It also contains utility functions to create error messages, headers, and other reusable components for the UI.

πŸ“¦ Other files

  • app_states.rs: Contains definitions for all ViewState variants (e.g., Connecting, Username, Chats, Invitation). Each state holds the variables that are relevant to that screen and helps manage the transitions between views.

  • main.rs: Contains the global state of the application, including the current ViewState, any potential errors, and the writer and receiver for communicating with the server. It defines the main logic for the Iced application, including handling user interactions and rendering the appropriate UI based on state.

🧩 Server Module

The server is responsible for managing the backend logic, including user authentication, message routing, and database interactions.

πŸ“¦ database_management.rs - Database Handling

This module defines the data access layer for interacting with the server’s database. It handles all queries related to users, messages, groups, and invitations.

  • It defines methods to read/write data to the database, such as checking if a user exists, retrieving chat histories, or adding/removing group members.

πŸ“¦ handler.rs - Client Request Handler

The handler module is responsible for processing incoming messages from clients, handling user authentication, chat management, and responding to client requests.

  • It includes logic for parsing messages like Username, Password, ChatMessage, and Invitation. Based on the message type, it performs the necessary actions and sends appropriate responses back to the client.

πŸ“¦ logger.rs - Logging System

The logger module periodically logs server activity, such as CPU usage, to help monitor system performance.

  • Every 2 minutes, it logs the server’s CPU usage to a file (cpu_log.txt), using the sysinfo crate to gather resource metrics.

πŸ“¦ main.rs - Server Initialization

The main.rs file serves as the entry point for the server application.

  • It initializes all necessary data structures (e.g., user sessions, chat history) and starts listening for incoming TCP connections. For each new connection, it spawns a new handler to process requests asynchronously.

πŸ“¦ utils.rs - Helper Functions

The utils module contains helper functions and macros used throughout the server to manage various tasks like message dispatching and error handling.

🧩 Protocol Module

The protocol module defines all shared data types and message structures used for communication between the client and the server.

πŸ“¦ data_structures.rs - Shared Data Structures

This module contains the core data structures that represent entities in the application, such as:

  • User: Represents a user with an username.
  • Chat: Represents a chat, which can be a direct message or a group.
  • Group: Represents a group, including its name and owner.
  • Invitation: Represents an invitation to join a group.

πŸ“¦ message.rs - Message Types

This module defines all the message types that can be sent and received between the client and server.

  • Message: The central enum that includes all message variants, such as Username, Password, ChatMessage, Invitation, ErrorType, and AckType. This is the backbone of the client-server communication.

πŸ“¦ lib.rs - Exporting the Protocol

The lib.rs module acts as a barrel for exporting all types and messages defined in the protocol module. It ensures that both the client and the server can access the same types and structures for communication.

So, the project is divided into three main modules: client, server, and protocol. The client module is responsible for the user interface and communication with the server, the server module handles all backend operations like user authentication and message routing, and the protocol module defines the shared types and messages exchanged between the two.

This structure ensures clear separation of concerns, making the application maintainable and scalable while allowing for easy communication between the client and server.


⚠️ Error Handling

Ruggine implements a structured error-handling system, ensuring that the client and server can gracefully handle most common failure scenarios.
Errors are exchanged using the Message::Error(ErrorType) variant from the shared protocol.

Server-side Errors

The server can generate different types of errors, all defined in ErrorType:

Error Type Scenario
InternalServerError An unexpected error occurred on the server side
WrongPassword User entered a wrong password during login
InvalidUsername Logout request or action received with a mismatched username
InvalidMessage A malformed or unexpected message was received
InvalidSender A Chat or Invite message was sent by a user different from from
GroupNotFound Requested group does not exist
UserNotFound Invitation sent to a user that does not exist
UserAlreadyInGroup Attempt to invite a user who is already in the group
InvalidInvitation User tried to join a group without a valid invitation
GroupAlreadyExists Attempt to create a group that already exists
UserAlreadyLoggedIn User attempted to log in while already logged in
InvitationAlreadySent User tried to send an invitation that has already been sent
OwnerAccessRightsRequired Non-owner user tried to perform an action that requires owner rights

When these errors occur, they are sent to the client as a Message::Error(ErrorType):

{
  "Error": "InternalServerError",
} 

Client-side Error Handling

On the client side, errors received from the server are clearly displayed in the GUI, using a red text area positioned below the relevant input fields or sections. This ensures users are promptly informed of any issues without interrupting their workflow.

Where errors are shown:

  • Login/Password errors: Displayed on the login or registration screens.
  • Group/Invite errors: Shown in the invitation or group management views.

Example scenarios:

  • If login fails (e.g., due to a wrong password), the user sees a clear error message such as β€œWrong password” without the application crashing.
  • Invitation errors (e.g., user already invited) are displayed in the invitation management section.

This approach ensures that all error messages are user-friendly and contextually relevant, improving the overall user experience.


πŸ› οΈ Tech Stack

Component Technology / Crate Purpose
Server Rust + tokio Async TCP handling and concurrency
Client Rust + iced Cross-platform GUI
Protocol serde, serde_json Message serialization/deserialization
Database SQLite + rusqlite Persistent storage for users and chats
Logging Custom in logger.rs CPU usage logging

πŸ“¦ Executable Sizes

Below are the sizes of the compiled executables for both the server and client applications:

Executable Size
server.exe ~ 4,91 MB
client.exe ~ 23,3 MB

πŸ–₯️ GUI

username_view β†’ Welcome/Login
Welcome and Login Screen
password_view β†’ Password/Registration
Password Entry and Registration Screen
connecting_state β†’ Connecting State with Error Message
Connecting State with Error Message
chat_view β†’ Direct chat + list
Direct Chat and Direct List View
chat_view β†’ Group chat + list
Group Chat and Group List View
invite_view β†’ Invitations & group creation
Invitation Management
chat_management_view β†’ Direct chat
Direct Chat Management
chat_management_view β†’ Search user for new chat
User Search for New Direct Chat
group_management_view β†’ Owner can manage members
Member Management (Group Owner)
group_management_view β†’ Member can leave group
Group Management (Member Can Leave Group)

About

Text Chat App developed fully in RUST for the System Programming course @polito. Tech stack: RUST

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages