Skip to content

Repository files navigation

English | 日本語

Prattle

A TLS-encrypted TCP chat server with a client CLI, Prattle demonstrates systems programming concepts such as async I/O, concurrent client handling, network protocol design, and graceful resource management.

Table of Contents

  1. Features
  2. Tech Stack
  3. Architecture
  4. Commands
  5. Prerequisites
  6. Running the Server
  7. Connecting as a Client
  8. Running Tests
  9. Project Goals

Features

  • TLS Encryption: All client-server communication is encrypted using Rustls
  • Concurrent Client Handling: Supports multiple simultaneous clients using both shared state and message passing in Tokio's async runtime
  • Command System: Simple text-based protocol with commands for chatting, actions, and server queries
  • Backpressure Handling: Recognizes slow clients and warns them when they fall behind
  • Graceful Shutdown: Cleanly handles server shutdown with proper client notification and connection draining
  • Strict Code Quality and Testing: Completely forbids unsafe, unwrap, and expect using Clippy and includes a comprehensive test suite, with all checks enforced in CI

Tech Stack

  • Rust - Chosen for performance and concurrency safety
  • Tokio - Async runtime for handling concurrent client connections
  • Rustls - Modern TLS library for secure encryption
  • Tracing - Structured logging for observability

Architecture

The server uses a broadcast channel architecture where:

  1. The server accepts TLS connections and spawns a task per client
  2. Clients select unique usernames upon connecting
  3. Messages are broadcast through a tokio::sync::broadcast channel
  4. Each client task concurrently manages receiving broadcasts, handling user input, and listening for the shutdown signal
  5. Graceful shutdown (via a separate broadcast channel) waits for two-way close_notify with timeouts, both per client and globally

Commands

/quit             Leave the server
/help             Show the help message
/who              List online users
/action <action>  Broadcast an action, e.g. /action waves
[anything else]   Send a regular message

Prerequisites

  • For Nix users, the toolchain is included as a flake.
  • Otherwise, install:

Running the Server

The server binds to 127.0.0.1:8000 by default, which can be overridden with the BIND_ADDR environment variable. BIND_ADDR will automatically be read in from a .env file if present.

just serve

Connecting as a Client

Simply execute the command just to connect to the running server using the client CLI. As with the server, the BIND_ADDR environment variable will be read from .env if present, falling back to the same default:

just

Running Tests

just test

The suite of unit and integration tests includes spawning a server and simulating multiple concurrent clients to verify:

  • Concurrent connection behavior
  • Username validation and collision handling
  • Command parsing and execution
  • Multi-client broadcasting
  • Graceful shutdown with edge cases

Project Goals

This project was built as a learning exercise to gain and demonstrate experience with:

  • Lower-level async programming working directly with Tokio
  • Networking concepts and protocol design
  • TLS/cryptography in practice
  • Rust's ownership model in a concurrent programming context

About

TCP/TLS chat server and client CLI built with Tokio

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages