Chat applications have become the most critical application on a smartphone. People always wish to keep their communication private with themselves. No one wants their chats or communication to be seen or read publicly. The chat messages are highly confidential information of the user. Every user wants their chats to be protected.
This is now done by Encrypting the chats. Encryption means the sender and receiver can only see the message. In a “Secure chat application”, the history of the messages can not be saved on the server.
No one would like their chats to be publicly exposed. For this, most recent chat applications like Whatsapp and Signal use End to End Encryption. It allows safe conversation with limited people.
The secure chat app allows users to send secure and instant messages. Secure chats are encrypted, which protects your communication from being intercepted by anyone. Encrypted messages have extra layers of protection.
Why does it require it to be secure?
Whenever we send a message to someone, it goes through a service provider server. The message will be sent in human-readable text if no encryption is used. This gives a chance to hackers to see the message at any point during the transmission. With encryption, the message is transformed from plain text into ciphertext. The cypher is encrypted with a key for the transfer. Then, a paired key transforms it back (decrypted) on the receiver’s device.
Most instant messaging apps today use end-to-end encryption. The encryption keys are stored at the sender and receiver ends, i.e. on users’ devices instead of on the server.
This method changes the message from human-readable text to encrypted text. This ensures that even the server or the provider you are using will not be able to see the message. So the message will only be visible in the readable text to the receiver you are sending.
What tech shall we use?
Firebase is Google’s multipurpose tool for developing different kinds of applications. This is very convenient for building chat applications. It has a few drawbacks also. Firebase helps you build any application at a fast pace and in an easy way. However, its optimization needs to be done in a way that will fully support chat apps. The pricing structure looks very comfortable to the eyes only until your application’s user base stays at a certain level. Firebase’s convenience also comes with a limit of 100,000 connections at a time. This might force you to switch your application to another technology. Developers must write the entire application from scratch if they are building your app with Firebase. This is not convenient in terms of cost and time.
- Websockets & Sockets.io
- Chat messaging APIs and SDKs
Finding the right tool or technology to build our app is challenging. There are so many options available in the market. Rather than trying all the available solutions, it is straightforward to go with chat API and SDK. This solution is straightforward to implement and use as a vendor or service provider. The API/SDK takes responsibility for reliability and scaling.
Architecture Diagram for a chat with the socket
This tutorial will use Socket.IO as it is raw and open source.
Database: Redis (preferred) or any SQL or NoSQL
FrontEnd: ready with chat UI
Backend: NodeJS Server with Express
The frontEnd is responsible for the following:
- Accepting data from the sender
- Displaying it to the sender
- Sending to the server via a socket connection
- Displaying it to the receiver
The Backend application is responsible for the following:
- Accepting the socket connection from the frontEnd
- Processing the data
- Storing into the database
The database will handle the socket connection Information and every user’s socket Id and keep the messages backup.
Building the application
- Write an express server with nodejs and assign it a port.
- Import the socket library in our code, create a connection object and assign it to the express server we created (now our socket is running on the same port as our express server)
- Write a code for handling the socket connections. Remember, sockets are events, so whenever any frontend (user) connects to our server via socket, it hits the “connection” event.
- When this event is triggered, we must get the user ID and socket id from the connection event and store them in our database.
- Now we know which user is connected to the socket via which socket id.
Now consider the above diagram and follow along:
- User A and User B wanted to chat with each other, so they opened the app.
- Once they connect to the server, the “connection” event will be triggered and we will store their user ID and socketId.
- Now user A writes a message and sends it over the connection; with the message, he also sends the user ID of user B.
- From the user ID of user B, we will get his socketId. We will emit one event from the server on that socket id with a message.
- For the socket to work and send data, the receiver should be connected to the socket.
Scenarios to handle:
- Send a notification to the receiver if he is not connected via the socket.
- Every time any user disconnects, the “disconnected” event gets hit. Handle that event and remove that user’s userId – socketID mapping from the DB.
- If the socketId of the user is not available in the DB – send a notification.
- When the application loads, fetch the list of users via some API so that the user IDs will be available.
Basic code snippet from node js and express app: