- Setup
- MVP
- User Interface and API design
- WebSocket vs HTTP
- Tools and Agile Methodologies
- Tech Stack
- Sequence Diagram
- Current Features
- Future Features
-
Clone the GitHub repository from here.
-
Ensure you have Python and Node.js installed on your machine.
-
Ensure you have MongoDB and Compass installed on your machine.
-
Open the project in your preferred IDE.
-
NOTE: You will see two '.env' files in the repository for this project. Whilst we acknowledge that it is NOT good practice to commit these files to GitHub, as this project is solely for demo purposes and contains no real user data, we included them for the sake of simplicity.
-
Navigate to the 'api' directory and run
python3 -m pip install -r requirements.txt
to install the dependencies for the Flask backend app. -
While still in the 'api' directory, run
python3 mongodb_initialization.py
to initialise the database. Use Compass to verify the creation of the 'encryptodevs' database and a 'users' collection containing one test user called 'abdio'. -
'cd' into the 'frontend/my-react-app' directory. Run
npm install
to install the dependencies for the React frontend app. -
Whilst still in the 'frontend/my-react-app' directory, run
npm start
and click http://localhost:3000 to launch the browser. The page will reload when you make changes. You may also see any lint errors in the console. -
Open a new terminal leaving the first open and cd to the 'api' directory. Run
python3 app.py
to start the backend server.
You can now test the app running on your local server. You can use Compass to view items (users and messages) in the MongoDB database.
Our aim as a group was to create a secure message app, modelled loosely on WhatsApp or Signal.
- Send secure text-based messages
- Users will be able to sign up and sign in
- Find and add friends/contacts
- Messaging notification (in-app)
- Call functionality
- Group chat functionality
- Sending audio/image messages
- Video calling
- Click profile picture in chat to view contact card
We chose to use the WebSocket protocol in preference to the more common HTTP protocol for this project as it enables real-time, bidirectional communication between the client and server - i.e. it maintains an open connection as users are sending messages back and forth, without the need for constant refreshing or reloading of the page to check for new messages (as would be necessary if using HTTP requests/responses). Although the use of WebSockets without an additional application layer extension is fairly crude, the functionality of keeping an open connection is crucial for instant messaging, and time limitations prevented us from adding more elegant extensions 'on top'.
- Real-time communication: WebSockets allow for instantaneous data transfer, making messages appear in real-time
- Bidirectional: WebSockets support two-way communication, enabling both the client and server to send and receive messages at any time in 'full duplex' mode
- Efficient: WebSockets maintain a single open connection, instead of relying on multiple HTTP connections
- Low Latency: WebSockets allow faster data transfer compared to the request-response model of HTTP, ensuring faster message delivery
- Scalability: WebSockets can handle a large number of simultaneous connections, making them suitable for applications with many users interacting in real-time
- GitHub 'Projects' was used as the communal organiser (Kanban) to keep track of tasks and workflow during the project
- Morning stand-ups as a group to briefly discuss work for the day before splitting into smaller groups
- After-lunch meetings on an ad-hoc basis to discuss any progress or blockers
- Daily retros from 4pm as a group, including code review, to merge pull requests and resolve any conflicts between versions, before pushing all completed changes to the main branch
- BackEnd - Python (Flask)
- FrontEnd - JavaScript (React)
- Database - MongoDB (with Compass for UI)
Although we had to abandon implementation of end-to-end encryption due to time constraints, the sequence diagram includes this functionality.
Our web app has the following features currently implemented:
-
- Password validation rules
- Username, email, and phone number 'uniqueness' check (against existing users in the database)
- Password encryption prior to database storage
-
- Graceful handling of incorrect user detail entry
- User authentication and authorisation
-
- password reset functionality
-
- All-users directory
- User login status indicator
-
- User-user private chat page with message logging on-screen
- Message storage to the database (unencrypted)
- 'Received message' alert for recipients not in the chat screen
Due to the strict time limitations associated with the project, we tried to ensure we kept our MVP to a very basic set
of features. However, we also identified some of the features we would wish to implement next, given more time. This
is not an exhaustive list, and most readers will be aware of the wide range of possibilities with such an app, such as
sharing of multimedia content, voice- and video-calling, use of emojis, group chats, mobile application
(iOS and Android) variants, use of local device contacts, chat history back-up and restoration, multi-device access
(such as mobile phone vs. desktop app vs. web app) ability to invite users to sign up to the app, and more.
The following details features we feel would represent the 'next steps', rather than an exhaustive list of all
possibilities, such as detailed above.
-
- an application-layer protocol which can be configured to sit on top of the lower-level WebSocket (transport-layer sort of!) protocol we have employed
-
- Initially in our MVP but removed due to time constraints
- A 'must' in today's security-conscious world
- Preferably using the Signal Protocol
-
- Ability to send a message to a user who is not logged in, and for the recipient to retrieve the message at next login
- Ability to reload chat history for each user-user pair on starting a 'new' chat
- Various possible options, including (but not limited to) an in-memory cache and queue service such as Redis/Redis Stream (on the back end)




