Chat applications are everywhere nowadays. The two best-known ones are probably Slack and WhatsApp. If you keep the amount of users low (e.g. less than 100) and the number of features limited, then it is actually pretty easy to create such a chat app.
I've create a small proof of concept chat app with Flask and jQuery. It runs in the browser.
We will keep it simple for this tutorial:
We store the messages - and only that - in a single table in a SQLite database.
We have an API which has one endpoint
messages which allows to
GET messages (filtered by id) and to
POST a new
The backend is done with Flask.
The front end is partially done with Jinja2 and partially with jQuery.
The folder structure is typical for Flask applications:
. ├── app │ ├── api.py │ ├── docs │ ├── __init__.py │ ├── main │ │ ├── __init__.py │ │ └── routes.py │ ├── models.py │ ├── static │ └── templates ├── Dockerfile ├── migrations ├── pyproject.toml ├── README.md ├── requirements.txt ├── start.sh └── wsgi.py
In the root directory, you have a
start.sh which uses the
wsgi.py to start a gunicorn
pyproject.toml gives some basic configuration.
The front end is in the templates directory.
How it works
When a new user opens the website, they get a session variable with a unique identifier. They receive all messages which were ever written (yes, in a productive system this is an awful idea) and they store the latest message ID they have seen.
Locally, jQuery asks every 500ms for new messages. For this request, it gives the latest message it has seen. This means most of the time the server returns an empty response.
When the client sends a new message, it is stored in the database.
The key CSS classes you have are:
message: It can either be one you received or one you sent.
conversation: The block that contains the stream of messages.
See this codepen for a nice the theme by Rumbiiha Swaibu.
A key point that took me a bit to implement is to add the most recent messages at the bottom and keep scrolling with the most recent ones - but only if you didn't scroll up before.
Why this is awful
Missing core functionality:
- Registration and Authentication: It is important who writes something. So people want to know the sender. In the system above, it is super easy to change the ID to somebody elses ID. To have arbitrary many IDs. It is hard to know who writes something. This topic comes with a lot of other topics like single sign on (SSO), 2FA / MFA, password recovery...
- Formatting: Allow users to format messages (bold, italic, links, math mode, ...)
- Chatrooms: People want to have private conversations. Conversations splitted by topic.
- Search: Once you have different rooms, you might want to search across rooms.
- File sharing
Other missing functionality:
- Voice over IP (calls) and Videotelephony (Video chat)
- Themes: Let users change the default looks
- Tennants: Besides chats / chatrooms, you might want to run the chat appliction as a service for organizations. They have their own (seperate) users and chat rooms. Maybe have some possibilities for customization.
- Scalability: If the database comes to its limits, you have to get a bigger machine. Other databases like AWS DynamoDB might have better behaviour.
- Backups were not even mentioned
- Polling: Pining the server twice per second is no big deal if you have few users. But the more users you get, the worse this will become.
- Pagination: Getting all messages in the beginning is a really bad idea.
- Front Ends: You might want way more. For example, native apps for smartphones.
- Protocols: Adding support for XMPP to allow usage of other clients (IRC seems to be outdated; Matrix could be an alternative according to this German post)
If you want to get the complete project and look at the code, here you are:
$ git clone https://github.com/MartinThoma/flask-chat.git $ git checkout v1.0
Free Chat Servers
In case you want to look at more professional chat server projects:
|Mattermost||MIT / GNU AGPL v.3.0||Go||not directly||✔️|