Key Things to Know: Enterprise Chat Architecture That Connects Millions of Users
In this article, take a look at some things to know about enterprise chat architecture that connects millions of users.
Join the DZone community and get the full member experience.Join For Free
Every architecture is designed to serve the purpose of the chat application, whether it’s between a doctor and patient or a customer and support agent, the result of transmitting the messages is the same, but the range of communication for different sectors differs. The chat infrastructure should possess the potential to serve communication for any industry, and that’s where the enterprise chat architecture comes into play.
Let’s get into how an enterprise chat architecture is engineered to withstand millions of concurrent users and messages.
Standard Version of a Chat Architecture
Basically, the standard chat architecture consists of two major parts; Chat Server Engine and Client Chat Part.
Client Chat Part — It’s chat application on the desktop, mobile device
Chat Server Engine — It’s the combination of several servers responsible for relaying messages operations
The server engine handles the entire operation of transmitting messages right from the message sent on a server to the delivery of messages on a client device with the help of tokens.
You might also like: Build a Chat Application Using Spring Boot + WebSocket + RabbitMQ
The Chat server engine consists of several components such as:
Chat WebSocket Server
WebSocket Client Library
Chat REST API
Chat Media Storage Server
The Standard version is pretty enough for handling a certain limit of users and messages, but when it comes to handling an enterprise project of connecting millions of users based on different communication channels (Text, Video, and Voice calls) and customizing the application, the infrastructure has to be upgraded.
That’s what [MirrorFly] Chat API architecture has done to meet today’s communication platform demand with Erlang, XMPP protocol, ejabberd server, and Mnesia database.
The Architecture of an Enterprise Chat Application
Ejabberd can inherently be broken up into three layers:
Interface Layer: This is the layer we have just talked about. It handles all the incoming data and outgoing data to the client.
Logic Layer: This layer is the most complicated of all. It handles all the XMPP logic, as well as many other features, e.g. HTTP bindings, access controls, extensible modules and hooks, etc.
Data Layer: This layer handles how data get stored in databases and ensures the integrity and constraints of data.
This layer handles incoming and outgoing data from the client. Its main functionality is to listen on a local port waiting for client connections, establish a connection with any clients or servers when necessary, and exchange data. It supports TCP/TLS connections as well as UDP transport, as is described in our last discussions. It serves as the interface between the outer world and the ejabberd server.
The logic layer is the main and most important part of the ejabberd system. Some of its functionalities include:
The client to server connection (typically on tcp/5222) is handled by the module ejabberd_c2s. The server to server connection (typically on tcp/5269) is handled by the modules ejabberd_s2s, ejabberd_s2s_in, ejabber_s2s_out. The HTTP bindings are handled by the ejabberd_http module.
The router handles the routing of most of the messages, i.e., when a Jabber client sends a to another entity, how is the message routed to the correct destination? The first ejabberd determines whether the message is a local or a remote one. It does so by looking at the "to" attribute to see if the host implied by the "to" attribute is hosted in itself. If so, the message is local; and is handled by ejabberd_local; otherwise, it is treated as an s2s message.
In addition to the core Jabber and Router logics, there is a large part of the ejabberd that can be plugged in only when necessary, and they are called modules. Modules can be started/stopped dynamically at any time, thus making the ejabberd server highly extensible even at runtime. Modules are widely used for various extensions (the so-called 'XEP's).
Do you want to change the core logic in the ejabberd server? No problem. Hooks are everywhere to help you. A hook is a way in which you can change the behavior of ejabberd by injecting your new code into the system without changing any existing code. For example, if you want to roll up your message filter to filter out messages you don’t want, you can add a module hooking to the “filter_packet/3” hook. If you want to keep track of all the messages clients sent, you can write a function hooking to ‘user_send_packet/3’.
All users (including real jabber client users as well as administrators) are stored the same way in ejabberd. Their privileges are determined by the groups they belong to. Hence, the access control modules in ejabberd allow us to distinguish users with their groups, thus providing different services for different users.
Utils and Libraries:
Some other libraries and utils exist in ejabberd for common purposes, e.g.: XML processing, SASL authentication, Encodings, Logger, etc. It is worth noting the ejabberd_logger is a very good logger module perfectly usable by any other project.
Ejabberd primarily uses mnesia as its “database.” Mnesia is, in fact, a high-performance key-value pair storage system built into the erlang library. It provides many features such as:
Replication. Tables may be replicated at several nodes.
Atomic transactions. A series of table manipulation operations can be grouped into a single atomic transaction.
Location transparency. Programs can be written without knowledge of the actual location of data.
Extremely fast real-time data searches.
Some of its features, such as replication and real-time searches, make it eligible for an extremely extensible database system. However, ejabberd does not enforce its use; it provides ODBC interfaces to allow the utilization of other databases whenever possible. For example, sometimes it might be more convenient to allow the user to authenticate using data stored in an existing database server, or there may be some relational data that need to be used for some purpose.
Generally, mnesia is suitable for fast key-value searches but performs pretty badly when you use it for “relational” lookups (using the mnesia: select the wrong way). Avoid relational data whenever possible (use key lookup) if you want to make good use of it.
The Benefits of Approaching Enterprise Chat Architecture
Reusability — The chat components can be easily redesigned for any other project.
Scalability — Each architecture is capable of handling the concurrent user base when the chat application (project) grows bigger and serves a larger audience base.
Customization and Integration — The architecture can be easily integrated and customized to any business needs irrespective of sectors.
Migration — Migration of components from one to another can be done easily without disturbing the other servers and components.
Through this architecture, the enterprise chat infrastructure is made simple, light-weight, customizable, and highly scalable. With a microservice architecture, Kubernetes, S3 bucket storage, Ejabberd, and XMPP Protocols, a complete enterprise chat API architecture is developed with autoscaling that can withstand more than 1 million concurrent user bases. Whatever the communication business and sectors, an enterprise chat architecture would best fit to scale your communication.
Opinions expressed by DZone contributors are their own.