Coder Social home page Coder Social logo

anarthal / servertech-chat Goto Github PK

View Code? Open in Web Editor NEW
7.0 3.0 3.0 811 KB

Chat app using Boost and C++

Home Page: https://anarthal.github.io/servertech-chat/

License: Boost Software License 1.0

CMake 1.25% C++ 69.13% Python 7.67% TypeScript 19.62% JavaScript 0.69% CSS 0.13% Dockerfile 0.84% Shell 0.68%
async aws beast boost cpp networking redis websocket

servertech-chat's Introduction

BoostServerTech Chat

This repository holds the code for a chat application written in C++.

Read the full docs here.

Build Docs Live server
Build Status Build Status Try it!

The BoostServerTech project

This is the first of the BoostServerTech projects, a collection of projects that showcase how C++ and Boost can be used for server-side code.

Architecture

The server is based on Boost.Beast, asynchronous (it uses stackful coroutines) and single-threaded. It requires C++17 to build. It uses Redis and MySQL for persistence.

The client is web-based and uses Next.js. It communicates with the server using websockets.

You can read more about the architecture in this section of the docs.

Local development

You can quickly run the chat application in localhost by using Docker Compose, by running in a terminal at the repo root:

docker compose up --build

Or you can learn about how to set up a traditional development environment here.

Going live in minutes

This project features a CI/CD pipeline that can deploy your code to your server in minutes. All you need is a Linux server with SSH enabled, or an AWS account to create one. You can find out more here.

Want to contribute?

Drop us a message in the cpplang Slack! Contributors are more than welcome!

servertech-chat's People

Contributors

anarthal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

servertech-chat's Issues

MySQL connection pool

Currently, we're creating, connecting, closing and destroying a MySQL connection for every request. This is inefficient. A connection pool can be much more efficient.

Integration tests sporadic failures in CI

If I'm not mistaken, this is because we're not waiting for the services to be healthy. Re-introduce health checks in docker-compose and use docker compose --wait

Redis Message spillover

Messages are currently stored using Redis streams. A stream per room (per "whatsapp group")
Messages are inserted with XADD, history retrieved with XREVRANGE

After a while the size will grow, and is time to store in mysql
Evaluate the usage of XTRIM, which IIRC is intended for the offloading process

Redis logging

We currently have Redis health checks disabled to reduce log verbosity - configure this correctly.

Run tests with sanitizers enabled

We currently run unit tests without sanitizers because Alpine Linux uses musl-libc, which doesn't support them. Consider other Linux distributions.

Integration tests are built in Release mode. We can consider running them with sanitizers enabled, but it can make sense running them with the same container build used for production.

Redis and MySQL hardening

We're currently running Redis without authentication, and MySQL with a blank root password (which almost equals no authentication). This is not terrible because these two services are never exposed outside of the Docker network (so an attacker must gain access to the server host to do anything), but it's not good practice.

MySQL root should have a strong password, and there should be a dedicated user with minimum privilege that's used in the webserver. We can create such user as part of a migration (see #11), and the password can be transmitted using AWS SSM. This requires the EC2 instance to call the AWS API though - so the CloudFormation scripts need to have IAM access to create a role for the EC2 instances.

Project documentation

Asciidoc (or GitHub markdown) documentation about the project architecture and best practices, as described in this document. Should be accessible from the "Docs" tab.

Benchmark Idea (also for performance regression)

  • Simulate N connection (say 10K client), all registering to the same channel, measure the time to fan out (IE delivery) a message to all the connected client. This will not take into account network problem that will require retry. Client should be on a separated machine.

  • Same as above but vary the number of client, to have a fancy scaling graph.

Reset password

This is an optional flow. Should be enabled if the backend gets credentials for the mailing service.

Client websocket reconnect

When the client fails to open a websocket connection or an error is encountered, it should somehow display this information to the user, and try to reconnect.

Feedback

We'd love to hear your feedback!

I you think something's improvable, you're stuck with something, or you've successfully used the app and want to share your experience, please share your thoughts by commenting on this issue!

Redis message persistance

When the Redis container is deleted and re-created in AWS, messages are lost. Place them in a volume so this doesn't happen.

Redis persistence is by default configured to just use RDB, which doesn't provide enough durability. Redis docs suggest that enabling AOF with the default settings should get us the desired performance/durability tradeoff.

API routing

Create a class that can dispatch to different handling functions depending on the HTTP request target, similar to what express or flask do.

Feature request: demonstrate calling sync APIs

As per this and this ML suggestions, there are some times where "do all async" isn't viable (e.g. because the database you're talking to has only a sync API). Demonstrate how this can be handled, e.g. by dispatching to a thread pool.

Message history - client side

When the user scroll up past the last message loaded by the client, it should request the server for more messages (requestMessageHistory). The server-side part is already done.

Authentication

Implement user registration and login.

User registration

Registration should require an email, a password and a username. All fields should be validated.

A set of password validation rules should be defined and enforced to prevent the user from choosing week passwords.

Email verification (as in sending an email with a unique token and validating it) is not required at this point.

Proposed API:

POST /register
{ "username": "xxx", "email": "xxx", "password": "xxx" }

Login

With email and password.

Suggestion: use a session cookie at least 128bit long, stored in Redis, valid for 7 days.

Login

With email and password.

Suggestion: use a session cookie at least 128bit long, stored in Redis, valid for 7 days.

requestRoomHistory parameter validation

Currently, startMessage is being passed to Redis without proper validation, which can cause vulnerabilities.

The proper way to implement room history requests is using a REST endpoint, not a websocket event.

Multithreading

We currently run a single-threaded io_context. Consider how we can make it multi-threaded (one context per thread vs. multiple threads and one context).

In-code documentation

Document the code internals so other users can read it. Like Beast does with its examples.

Mailing service client

Implement a client class to interact with an external mailing API. It will be used for signup & password recover flows. It should demonstrate how to call external APIs using Boost. We can consider using the not-yet-in-boost Requests library.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.