- Rust 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| client | ||
| common | ||
| docs | ||
| server | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE-APACHE | ||
| LICENSE-MIT | ||
| README.md | ||
| renovate.json | ||
chat-project
A chat server and client written in Rust. Started as a "let me learn async Rust" project, kept growing.
Not production ready, see the bottom for what's missing.
Layout
common/shared types, the wire protocol, and the traits both client and server build onserver/the actual server: auth, message routing, SQLite storageclient/terminal client, mostly for testing the server
Why this might be interesting
Client and server don't talk to TCP or WebSocket directly, they're written against two small traits:
pub trait ConnectionReader<T>: Send {
async fn read_message(&mut self) -> Result<Option<T>, BoxError>;
}
pub trait ConnectionWriter<T>: Send {
async fn write_message(&mut self, msg: &T) -> Result<(), BoxError>;
}
Each transport just implements these once (tcp.rs, ws.rs on both
sides). All the actual logic, auth, routing, the client's input loop, is written once and doesn't care which transport it's running over.
Wanted WebSocket support alongside the original raw TCP without
duplicating the whole connection handler, and this is how that ended
up working.
Protocol details (message shapes etc) are in PROTOCOL.md.
For new contributors check out Architecture.md too.
What it does right now
- Register / login, passwords hashed with argon2
- Accounts persisted in SQLite, survive a restart
- Session tokens, log in once, client saves a token and auto-logs-in next launch
- Works over raw TCP or WebSocket, same protocol either way
- Send a message to another user by username, if they're online
Running it
cargo run --bin server
then in another terminal:
cargo run --bin client
It'll ask tcp or ws, then drop you at a > prompt:
/register <username> <password>
/login <username> <password>
/msg <username> <message>
What's missing / RoadMap
- No END to End encryption at all right now, server sees everything in plain text. This is the big one before it's actually private.
- Offline users just don't get the message, nothing's queued
- No web client yet (WebSocket support exists server-side for exactly this reason, just haven't built one)
- Tokens don't expire
Contributing
Open to it. CI runs cargo fmt --check + clippy and trivy, only clippy and trivy need to pass.
For anything bigger than a small fix, open an issue first so we don't
duplicate work.
License
MIT or Apache-2.0, your choice, see LICENSE-MIT / LICENSE-APACHE.