Chat: Overview and configuration


The aim of this tutorial is to create a multi-user real-time chat system. Users will have access to a very simple interface, with a small form for entering their name and messages, and underneath the list of sent and received messages.


To carry out this development, we're going to use two specific technologies (which are natively managed by Temma): SSE (Server-Sent Events), and ZeroMQ network communication.

  • SSEs are used to send messages from the server to browsers connected to the chat.
  • ZeroMQ network connections are used for communications between controllers and a "message broker", whose role is to forward messages received to all controllers sending SSEs.


In addition to the controller that displays the web interface, there are two controllers that manage data exchanges between the browser and the server:

  • Browsers connect to the Event controllers as soon as the web page is loaded. These controllers send SSEs each time a message has been sent by a user. So there are as many Event controllers running as there are browsers connected to the site.
  • Message controllers are called in AJAX by browsers when a message is sent by a user.

1.3How it works

Here's an overview of how a message is sent to the server:

  1. The message (and the user's name) is sent to the server via a standard AJAX request.
  2. The Message controller receiving the message opens a ZeroMQ socket of type PUSH to the broker, to transmit the message.
  3. The broker, which was in read-only mode on its PULL socket, receives the message. It forwards it to its outgoing PUB (publication) socket.
  4. All Event controllers connected to the broker's PUB socket with a SUB (subscription) socket receive the message. They forward it via SSE to the browsers connected to them.

2Configuration file

So there are four different ZeroMQ sockets: PULL and PUB are used by the broker, PUSH are used by the Message controllers and SUB are used by the Event controllers.

In the etc/temma.php configuration file, we'll declare a different data source for each type of ZeroMQ socket. Even if not all sockets are used at the same time (the broker uses two of the four, the controllers only one), this is not a problem, as the connections are not really opened until they are used for the first time.

Here are the contents of the file:


return [
    'application' => [
        'dataSources' => [
            'zmq_client_push': 'zmq://PUSH@',
            'zmq_broker_pull': 'zmq-bind://PULL@',
            'zmq_broker_pub':  'zmq-bind://PUB@',
            'zmq_client_sub':  'zmq://SUB@',
        'enableSessions' => false,
        'rootController' => 'Homepage',

The data sources are:

  • zmq_client_push: PUSH socket used by the Message controller to send the message it has received to the broker.
  • zmq_broker_pull: PULL socket used by the broker to receive messages sent by Message controllers.
  • zmq_broker_pub: PUB socket used by the broker to redistribute messages received to all Event controllers.
  • zmq_broker_sub: SUB socket used by Event controllers to receive messages published by the broker.

On line 11, sessions are disabled, as we won't be needing them.
At line 12, we define that the root controller (the one that responds for URL "/") is the Homepage object.