How To Build A Messaging Chat App

・11 min read
How To Build A Messaging Chat App

Messaging apps certainly changed the way we communicate. They gave us the opportunity to instantly interact with our friends and family just like we would in flesh. The popularity of applications like WhatsApp, Facebook Messenger, Slack or Viber has raised the interest of many tech companies.

If you are one of those people who are wondering how to create a successful messaging chat application, this article is for you!

Why build a chat application?

To have a successful app you have to understand why they are so popular among people, why they use them.

According to Facebook, over 80% of adults and 91% of teenagers message every day making it a core part of everyday life. Messaging takes up 67% of all channels of communication.

People use live chats because they are convenient, instant, provide records of conversations, and can be used anywhere.

Worth adding is that in China, an average user has 3 different messengers installed on their smartphone.

As far as the competition is going, WhatsApp is definitely the most popular with 1.500 million users, followed closely by Facebook Messenger with 1.300 million. There are a lot of apps to compete with, so you need to put extra effort to stand out and get users’ attention.

What are the core features of a messaging app?

There are a lot of features that you can implement in your application, but you should consider what are the must-haves by analysing the most popular solutions and thinking about what you enjoy the most.

  • register
    • depending on the chat app users can register by entering a mobile number or creating an account
  • status
    • users can create a personal profile with details like number, profile image, name
  • search
    • give users the ability to search for their friends
  • voice calls
    • applications like WhatsApp or Viber have the voice calling features
  • video calls
    • you can also have a video call features
  • group chats
    • enable your users to chat with multiple people at once, especially useful when making group plans
  • notifications
    • a crucial function of any messaging application - your users will receive a quick notification when they get a message
  • sharing
    • sharing photos and videos with your friends is an extra advantage of using messengers

Benefits of chat applications

Although messaging applications are most frequently used by normal people, they are making their way into the business world as well. The importance of instant communication between the coworkers is rising. Video conferencing applications are also gaining popularity in industries like:

  • eCommerce
    • uses live chat to help customers face-to-face. A custom application could also provide the support employees with customers’ purchase history and access to their shopping cart.
  • Finance
    • video conferencing used to chat with clients while discussing investments and financial history. Chat applications lower the customer drop-off rate thanks to instant replies.
  • Healthcare
    • video apps are used to host therapy sessions and health advice improving care coordination.

What to choose: ready-made vs custom solutions?

An example of a ready-made solution is the so-called white label aps. A white label application is an app that displays your own brand instead of one of its creators. The app’s creator gives you the rights to claim the app. As a client, you have a legal right to boast about having built it yourself. A perfect example of such a solution is Reve Systems White Label Chat Application providing you with features like audio and video calling, media sharing or location sharing.

Another example of a white label application is Zangi, which allows you to fully customize the look of the product with its own colors, logo and features.

Apart from the white label, there are also ready to build solutions. This market primarily consists of messaging as a service and backend as a service. Messaging as a service are dedicated to building messengers - they are database layers with a messaging layer on top - like Quickblox and Tokbox. Those solutions offer a higher level API which saves development time, but at the same time, you lose some of the flexibility.

As fat as the backend as service goes they are built for a greater range of use cases. Some of them are: Firebase, Pusher or Pubnub. They definitely require more development since you have to design a messaging API and build the messaging layer yourself. However, adding new features in the future is much easier.

A cool solution worth checking out is also Applozic - a ready SDK for building chat applications with a secure and scalable backend.

If you do not know what to use ready-made solutions you can build one from scratch. When doing so there are some key steps to consider:

  1. find a platform: Native or Hybrid - knowing if your application will be targeted towards Android or iOS users is crucial.
  2. define the target audience - who does your app target? The general population of business professionals? Your target audience will influence the range of features implemented in your app.
  3. MVP - determine how should the MVP look like and what are the must-have features
  4. development time - when it is time to start your development you need to find developers: remotely or in-house. Finding an experienced team can be tricky, you can read more about it in our article …

WebSockets vs WebRTC

WebSockets are bidirectional mechanisms for browser communication. A web browser connects to the web server by establishing a WebSocket connection. WebSockets have great concurrency and optimization of performance. They are great for building responsive and rich web applications.

On the other hand, WebRTC enables sending data across a browser without the need to relay that data through a server. WebRTC allows setting up peer-to-peer connections to other web browsers quickly and easily. It is great for building dating services and social network applications.

For a chat application, the better choice would be to use WebSockets as the communication is simpler and they provide us with more features and benefits.

For a more in-depth comparison, take a look at WebSockets vs WebRTC.

How to build a messaging app: step by step

There are a couple of different ways to build a messaging app. I will focus on building the back-end with Amazon ElastiCache for Redis and the front-end using React + Socket.io client. However, you can also build with:

  • AWS
    • this will allow you to create a serverless real-time chat application with AppSync. AWS AppSync is a fully managed GraphQl service. It can be used to build collaborative mobile and web applications with responsive user experience with online and offline capabilities. More information can be found in the AWS AppSync Developer Guide
  • Socket + Node.js - Node.js combined with Socket allows us to build a real-time chat application. The most important advantage here is the fact that with Node.js JavaScript is used to build both the front-end and the back-end of your application. More about this you can find here: How to build a real time chat application in Node.js using Express, Mongoose and Socket.io

Building a chat application with Amazon ElastiCache for Redis

As building a chat application requires a communication channel which will be used to send messages to be further redistributed to other participants. Such a communication can be implemented using the PubSub pattern.

A PubSub pattern is implemented on a backend server to which the client communicates using WebSockets. It is also important to mention that in this case, it is good to use a multi-server architecture, which increases reliability and elasticity. In this type of server architecture, a client makes a WebSocket connection to a load balancer, which forwards traffic to a pool of servers.

Backend

1. Setting up Redis with WebSockets

declare HTTP application and WebSockets using express

A WebSocket is established with a PubSub application when the web client is opened in the browser. The application assembles data for existing members and messages.

var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;

establish connections to the Redis cluster

The application must establish multiple connections to the Redis cluster: one needed to make updates to Redis data model and to publish messages on a topic. Other one for each of the topic subscription

var Redis = require('ioredis');
var redis_address = process.env.REDIS_ADDRESS || 'redis://127.0.0.1:6379';

var redis = new Redis(redis_address);
var redis_subscribers = {};

function add_redis_subscriber(subscriber_key) {
   var client = new Redis(redis_address);

   client.subscribe(subscriber_key);
   client.on('message', function(channel, message) {
      io.emit(subscriber_key, JSON.parse(message));
   });

   redis_subscribers[subscriber_key] = client;
}

add_redis_subscriber('messages');
add_redis_subscriber('member_add');
add_redis_subscriber('member_delete');

serialize objects to JSON

Objects are serialized to be stored as values in Redis data types and published on PubSub topics. Those strings have to be deserialized to a JavaScript object before being published over WebSockets.

io.on('connection', function(socket) {

... application business logic ...

}

establish connections with client

2. Initialize a new client connection
  1. The current list of members is retrieved.
  2. Unless this is a client reconnecting, a new member is created with a random user name and avatar URL, and then stored in a Redis Hash.
  3. A truncated list of historically recent messages is retrieved.
var get_members = redis.hgetall('members').then(function(redis_members) {
   var members = {};
   for (var key in redis_members) {
      members[key] = JSON.parse(redis_members[key]);
   }
   return members;
});
3. Message handling

When a new client is completing its initial WebSocket connection we must define a message handler for messages to be sent by the new client.

  • define message handler for messages
  • add the message to the message history
  • publish the messages topic
socket.on('send', function(message_text) {
var date = moment.now();
var message = JSON.stringify({
   date: date,
   username: member['username'],
   avatar: member['avatar'],
   message: message_text
});

redis.zadd('messages', date, message);
redis.publish('messages', message);
});
4. Disconnection handling

When a heartbeat from the Websocket established when a client connects to the server fails, a disconnect event is fired.

socket.on('disconnect', function() {
   redis.hdel('members', socket.id);
   redis.publish('member_delete', JSON.stringify(socket.id));
});

Redis.HDEL is used to remove client from the member Hash and since we notified all participants of a new member joining the chat room, we must also notify all participants that a member is leaving the chat room.

5. Application stack deployment using AWS CloudFormation

CloudFormation gives developers and system administrators an easy way to create and manage AWS resources. It provisions and updates those resources. Go here to launch a stack. CloudFormation will create an Elastic Beanstalk environment, application and configuration template. It also creates the ElastiCache cluster for Redis and Amazon EC2 security groups for the load balancer, application servers, and Redis cluster.

To modify the configuration of the Elastic Beanstalk Nginx proxy configuration to support WebSockets we must enable sticky sessions so that the same instance responds when the client makes two consecutive HTTP requests to upgrade the connection to use Websockets. We must make a small configuration change to Nginx by using the .ebextensions mechanism for Elastic Beanstalk.

container_commands:
   enable_websockets:
      command: |
        sed -i '/\s*proxy_set_header\s*Connection/c \
                proxy_set_header Upgrade $http_upgrade;\
                proxy_set_header Connection "upgrade";\
         ' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

Frontend

  1. First of all, create a project using

npx create-react-app chat-app-client

  1. Then, install socket-io-client with

npm i socket.io-client

  1. Use App.js to create a simple view with a list of messages and input to send a new one
  2. To handle creation and destroying of socketIOClient use useEffect

Let’s take a look at the code:

import React, { useState, useEffect } from "react";
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://127.0.0.1:3000";
function App() {
  const [messages, setMessages] = useState("");
  const [inputVal, setInput] = useState(“”);
 const handleSubmit = () => socket.emit('send', inputVal);
  useEffect(() => {
    const socket = socketIOClient(ENDPOINT);
    socket.on("messages", data => {
      setMessages(data.messages);
    });
  }, []);
  return (
    <div>   
      <div>
        { messages.map(message => <p>{message}</p>) }
      </div>
      <form onSubmit={handleSubmit}>          
        <input type="text" value={inputVal} onChange={val => setInput(val)} />
        <input type="submit" value="Send" />
      </form>
   </div>
  );
}

Conclusions

This article was created to help you build your own messaging chat application since their popularity is constantly growing and many companies aim to create their own solutions similar to WhatsApp or Facebook Messenger.

When building your solution remember to implement features like notifications, video and text chat, file sharing and group creation.

If you are looking for a team of experts to support the development of your messaging application, contact us. With years of experience, we will ensure your product will be able to compete with the biggest names out there.

Related articles