Chat: Web interface


1Controller

We'll only look at the controller that loads the web interface.

The Message and Event controllers, which communicate with the server to send and receive messages, are described in detail on the next page of the tutorial.

Here is the code for the Homepage controller, saved in the file controllers/Homepage.php:

<?php

/** Root controller. */
class Homepage extends \Temma\Web\Controller {
    /** Root action. */
    public function __invoke() {
        $this->_view('homepage.tpl');
    }
}
  • Line 4: Definition of the Homepage controller.
  • Line 6: Definition of the __invoke() method, corresponding to the controller's root action.
  • Line 7: The method contains only the instruction defining that the template to be used is the homepage.tpl file.

2Template

Here's the template code for templates/homepage.tpl, which is loaded when the user accesses the service:

<!DOCTYPE html>
<html>
<body>
    {* message sending form *}
    <input id="from" type="text" placeholder="Name" autofocus>
    <input id="text" type="text" placeholder="Message">
    <button onclick="sendMessage()">Send</button>

    {* list of received messages *}
    <ul id="liste"></ul>

    {* javascript code loading *}
    <script src="/chat.js"></script>
</body>
</html>
  • Lines 5 to 7: Form for sending messages. The first field waits for the user name, the second for the message text. By clicking on the "Send" button, the Javascript function sendMessage() is executed, sending the form data to the server with an AJAX request.
  • Line 10: This list will contain an additional element each time a message is received.
  • Line 13: The file containing the Javascript code is loaded.

3Javascript code

Here is the Javascript code saved in the www/chat.js file:

/* *** MESSAGE RECEPTION BY SSE *** */
// connection to SSE source
const evtSource = new EventSource("/event/fetch");
// listen to events sent on the "msg" channel
evtSource.addEventListener("msg", function(event) {
    // creation of the DOM <li> element
    const newElement = document.createElement("li");
    // deserialization of received event
    var evtData = JSON.parse(event.data);
    // add message to list
    newElement.textContent = evtData.from + " : " + evtData.text;
    // add item to list in page
    document.getElementById("liste").appendChild(newElement);
});

/* *** SENDING MESSAGES TO THE SERVER *** */
// function called to send messages to the server
function sendMessage() {
    // retrieve form values
    const from = document.getElementById("from").value;
    const text = document.getElementById("text").value;
    // creation of POST parameters object
    const formData = new FormData();
    formData.append("from", from);
    formData.append("text", text);
    // AJAX data transmission
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/message/broadcast", true);
    xhr.send(formData);
}

The first part of the code opens the SSE communication to receive events from the server. The second part is the function that is called when a message is sent.

  • Line 3: Connection to the SSE event source, available at URL /event/fetch.
  • Lines 5 to 14: Code executed each time an SSE event is received on the "msg" channel.
    • Line 7: Creation of a <li> node, corresponding to the element that will contain the message, and which will be added to the list in the web page.
    • Line 9: Data deserialization (received in JSON format).
    • Line 11: In the <li> element created above, we write a text consisting of the message sender's name, followed by " : " and then the text message received.
    • Line 13: The <li> element is added to the list in the web page.
  • Lines 18 to 30: Function called when the user clicks on the form's "Send" button.
    • Lines 20 and 21: Retrieve form data.
    • Lines 23 to 25: Creation of a FormData object containing form data.
    • Lines 27 to 29: AJAX data transmission to URL /message/broadcast.