In this series of tutorials we will learn how to build a chat application hosted by the ESP32. Since the ESP32 is a resource constrained device, our application will have very simple functionalities and will be mainly focused on teaching the technologies that will support it, such as:
The expected outcome, at the end of these of tutorials, is shown below in figure 1.
To build this application we will only need an ESP32 board and some device to to test the chat as a user (a computer with a web browser or a smartphone is enough). I’ve used a a ESP32-E FireBeetle board from DFRobot to perform all my tests.
Why a Chat application?
In a real application scenario, it is extremely unlikely that a chat application would be implemented in a microcontroller. These applications are usually complex and require scalability. They need to handle many users and many messages, which requires more resources than a device such as the ESP32 can offer.
Nonetheless, a simplified chat application has many interesting challenges that can be solved using some of the technologies supported by the ESP32. Furthermore, it is something practical that is fun to build and to see working.
As such, we are doing a chat application for teaching purposes, since it will allows us to cover the basis of some interesting technologies that you can then use in other projects. Naturally, we will support few users and the set of functionalities we will implement will be reduced. Also, we are not going to worry much about performance.
The requirements and architecture of the application
Our chat application will be very simple. There will be a single chat room to which all the users can connect to and disconnect from. A connected user can send a message, that will be received by all the other users. There is no concept of history and messages sent are only delivered to the users currently connected.
A chat application typically requires that the messages sent between connected users are delivered in “real-time”. Here, we use the term “real-time” to indicate “sending the messages as fast as possible”, since the term “real-time” has a different meaning in the world of embedded systems.
As such, websockets are one of the technologies supported by the ESP32 that fit perfectly this requirements, allowing the chat clients to maintain a persistent connection to the ESP32 (the ESP32 will be acting as a websocket server). Then, whenever a chat client produces a message, the ESP32 will be responsible for delivering it to all the other participants of the chat.
To keep things simple, when the ESP32 receives a message, it will broadcast it back to all the websocket connections, meaning the original sender will also receive the message back. Naturally, in a more realistic application scenario, we could exclude the sender when broadcasting the message.
Taking in consideration that the sender will later get its own message back, we will simplify the client code by only displaying messages received. As such, when the client sends a message to the server, it won’t immediately display it in the UI. That way, each client can always display all the received messages from the ESP32 without having to exclude their own. Once again, this is a simplified approach since, in a real application scenario, there are many situations that would justify the client keeping a copy of the message it sends.
Figure 2 displays the communication diagram described before.
Besides displaying the chat messages, our application will also be able to display when clients connect and disconnect from the chat.
It is important to take in consideration that we are going to do some simplifications in our code, to make it simpler. For example, we won’t be treating all the error situations (message could not be delivered, websocket connection failed, UI fields not properly filled, etc…). Naturally, in a real application scenario, we should take care of all the errors.
Other important aspect to mention is related with security. The files will be delivered over HTTP and the websocket connections won’t be encrypted. This means that all the communications won’t be secure and this application should be used only for testing purposes.
The implementation of the chat application will be divided in multiple parts. At the end of part 1 we will already have a basic prototype working and then we will build the rest incrementally.
- Part 5: We will start handling the client connected and disconnected events, displaying a message in the chat window whenever they occur.
The practical application we are going to develop here is built on top of many tutorials we have already covered on TechTutorialsX. Although each part of this tutorial explains the code used, you may consult the posts below for more details.
- Async HTTP web server: How to get started using the Async HTTP web server library, which supports both serving files and websockets. This post is a basic “Hello World” tutorial that teaches how to configure a simple route to answer to HTTP GET requests.
- Async HTTP server – Websockets: How to setup a websocket endpoint in the async HTTP server.
- Async HTTP server – websocket broadcast: How to broadcast messages to all the websocket clients.
- Nlohmann/json library: An introduction to the basic functionalities of the Nlohmann/json, a C++ JSON library. It covers serialization and deserialization, amongst many other features. Although we won’t use it in the chat application tutorials, if you prefer a JSON library that is closer to the Arduino style, I strongly recommend ArduinoJson. The JSON handling part of the code should be pretty straightforward to adapt.
- System time and SNTP: How to configure the system time using SNTP on the ESP32. This functionality will be used for the timestamping of the messages.
- ESP32 SPIFFS file system: How to get started with the ESP32 SPIFFS file system. This tutorial explains how to initialize the file system and write a file.
- Arduino IDE SPIFFS Upload plugin: How to use the Arduino IDE SPIFFS file uploads plugin, which allows to upload files to the SPIFFS file system of the ESP32 in a very simple and convenient way.
- Serving HTML from the ESP32 file system: How to serve HTML files via HTTP from the ESP32 file system, using the Async HTTP web server.
- Serving CSS from the ESP32 file system: How to serve CSS files from the ESP32 file system.