This repository demonstrates typical chat application's (WhatsApp) API server backend architecture using Web Socket technology, Django REST Framework, RabbitMQ server.
Steps to run application
- Clone repo: git clone "https://github.com/exceptionalvic/whatsapp_api.git"
- Create a virtual environment and activate it:
python -m venv env - Run
pip install -r requirements.txt - Setup database either PostgreSQL and add credentials in
settings.pyfile or use default db.slite3 (not suitable for production)
DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql_psycopg2", "NAME": "whatsapp_api", "USER": "postgres", "PASSWORD": "mypassword", "HOST": 'localhost', "PORT": "5432" } }
Replace NAME, USER and PASSWORD with your actual PostgreSQL RDBMS database. You need to have PostgreSQL installed in your local machine.
- Run
python manage.py migrate - Setup your RabbitMQ server in
settings.pyfile
RABBITMQ_HOST = '127.0.0.1' RABBITMQ_PORT = 5672 RABBITMQ_USER = os.getenv('RABBITMQ_USER') RABBITMQ_PASS = os.getenv('RABBITMQ_PASS')
CHANNEL_LAYERS = { "default": { "BACKEND": "channels_rabbitmq.core.RabbitmqChannelLayer", "CONFIG": { "host": f"amqp://{RABBITMQ_USER}:{RABBITMQ_PASS}@127.0.0.1/", }, }, }
To use RabbitMQ, you will need to have RabbitMQ installed and started on your local machine, then access the manager interface to create a user and password if you don't want to use the default username: "guest" and password: "guest". Refer to this documentation for help.
- Start django ASGI server with
python manage.py runserver. Because Django Channels is installed with daphne, this automatically runs the django ASGI server suitable for websocket connections. - Create a .env file at the root of your project and add your RabbitMQ configs and secret key, you can repeat that for database. This is suitable for production environment.
Django version 3.2.6, using settings 'whatsapp_api.settings' Starting ASGI/Channels version 3.0.4 development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. HTTP/2 support enabled Configuring endpoint tcp:port=8000:interface=127.0.0.1 Listening on TCP address 127.0.0.1:8000
- Open another terminal to run the chat subscriber service
python manage.py run_chat_subscriberThis service worker listens to receive messages from RabbitMQ exchange via publisher and sends them to the appropriate web socket channels. This is a kind of pub/sub custom approach using Django Channel_Rabbitmq package which have async limitations.
uWSGI a performant server with inbuilt web sockets support is another alternative approach using pika module that connects with RabbitMQ broker without relying on Django Channels.
- Create account using the Swagger API docs at http://localhost:8000/api/v1/docs/ which also contains API docs for other functions.
- Authenticate a new user
user1and create a Chatroom using your preferred Client like Postman or Insomnia. - Open another tab in your Client, create and authenticate another user
user2and note the user account id. - Join the Chatroom created by
user1using thechatroom_idto join the web socket channel layer for this chat room - Then open another tab in the client and create a Web socket request method
WSusuallyws://. This tab will listen to messages and chats and notifications going on on the chatroom created by first user1 which user2 has joined. To test, in the URL field of your client (Postman or Insomnia), type in 127.0.0.1:8000/ws/chat/<chatroom_id>/?token=your_jwt_access_token gotten from authentication API endpoint response body - Whenever user1 sends a message, notice the response in the channel
- To run tests, run
pytest
Sample broadcasted message to chatroom via web sockets, all connected chatroom members see new messages.
- Uploading files in chunks to handle large files
- Usage of uWSGI server gateway for performance with embedded web socket capability