How to create a private chat on socket.io with Symfony: 5 steps guide

Private chat

Today we will create a very simple private chat using socket.io. “Private chat” means that users can join only if they have permission. On the server of the Symfony app the user’s rights will be checked. Also, the chat will save the correspondence history in a database.

What it should look like

Let me try to describe the algorithm:

  1. Client connects to the socket.
  2. After successful connection, the client “call”s the event, “join”s and sends the id of the room to which he wanted to connect and his API key (the user’s API key in the symfony app)
    • When the chat script handles the “join” event it sends a request to the symfony app API
    • In the case of a “successful” response, the API adds the client into the room
    • In the case of an “unsuccessful” response, the API sends the client a refusal message and disconnects it from the socket.
  3. After the client gets a response about their successful entrance into the room, they can then send messages there.
  4. When the client sends messages, he causes a “message” event
    • when the chat script handles a “message” event it runs a few things:
    • the received message is processed, it must include the current date and the ID of the user who sent it
    • a ready message is sent to all chat users except for the user who sent it
    • a ready message is sent to the symfony app.
  5. Once the message is received, clients are sent the “message” event which they must then handle

Step by step instructions

Therefore, the first step in creating such a chat, is to make an API in Symfony. The API must implement the following methods:
– GET /chat/{id}/join – for checking the right of access
– POST /chat/{id}/message – for saving messages in database
– GET /chat/{id}/messages – for acquiring the message history

The first and second methods are called only from the chat script. The last one is called by the client directly.

The authorisation passes through the API key which is in the request header. In response, we refer http-error codes. With a successful authorization we return the “user” entity (from this point on we will use user.id when sending messages from the chat script).

The second step is the creation of the chat script. It took me a long time, but I’d like to share with you a small, simple example from which I’ve removed the additional logic, (which is not further discussed):

Here’s an example of the configuration file:

The third step is the creation of a client. For our example we’ll consider a browser client on javascript. Actually it doesn’t really matter which platform the client is on, as the client’s actions should be the same regardless of platform.
Here’s an example of a client:

At this point everything should work on your local computer. After local testing we need to run it on the server, where the chat script will always be performed. Also we need to ensure that the script will be available on the 80 port, not on the 3000 as described in the code.

The fourth step is to run our script on the server. We need to do it in such a way that the script constantly runs and is automatically restarted if a mistake occurs. For this we create a configuration file for supervisord:

Now we need to create a symbolic link to the configuration file:
sudo ln -s /home/ekreative/sites/chat-server/supervisord/chat-server.conf /etc/supervisor/conf.d/

After that we need to restart supervisor:
sudo service supervisor restart

And finally, the fifth step – configuration of the apache-server for access to the socket through the domain and 80 port. For this we need to activate the following apache modules:
sudo a2enmod proxy
sudo a2enmod proxy_wstunnel

After that we can write the next configuration:

Restart the server:
sudo service apache2 restart

Enjoy!