In this tutorial I'm going to show you how to build a simple real-time chat app with PHP using Ratchet PHP WebSockets library with a simple and nice UI, and of cource the source code of this tutorial you can find it in the last of this tutorial.

Before we go, you may ask :

What is Ratchet?
Ratchet WebSockets for PHP
Ratchet is a loosely coupled PHP library providing developers with tools to create real time, bi-directional applications between clients and servers over WebSockets.

What is a WebSocket?

WebSocket is a protocol for creating a fast two-way channel between a web browser and a server. WebSocket overcomes limitations with HTTP to allow for low latency communications between a user and a web service.


So now let's get started:

Step 1
Create a new folder for your app in (www/htdocs) folder on your server, for example AcruxChat.

Step 2
Open your terminal in your app folder "AcruxChat" and then install Ratchet php library by the following command using composer :

$ composer require cboden/ratchet


Wait!! Don't know what is composer?
Composer is an application written in PHP that will manage external PHP libraries within your project.
Ratchet requires React, Guzzle, and Symfony2's HttpFoundation in order to work. It would be a pain in the butt to have to download Ratchet, then download those three libraries in order to make Ratchet work. Oh, and make sure you download the right versions or else there could be problems. But, you don't have to worry about that, thanks to Composer :)

Step 3
After installing Ratchet, you will see in your app folder that [vendor folder , two other files] generated by composer.. that's good.
Now we need to create the index file, but before that we need to add jQuery (Javascript plugin) to use it in our app, after downloading it .. put it in app folder that we called "AcruxChat".

Creating the index.php file
Create index.php file in your app folder and write the following code inside it :
<?php 
session_start();
if (!isset($_SESSION['name'])) {
 header("location: name.php");
}
$name = $_SESSION['name'];
?>
<!DOCTYPE html>
<html>
<head>
 <title>hello chating realtime</title>
 <script src="jquery.min.js"></script>
 <style type="text/css">
  body{
   background: #edeff1;
      font-family: sans-serif;
  }
  #chating{
      height: 280px;
      overflow: auto;
  }
  #msgField{
   position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      width: 100%;
      padding: 8px;
      outline: none;
      box-sizing: border-box;
  }
  #uStatus{
      margin: 0;
      padding: 8px;
      background: #e6e6e6;
  }
  #chatBox{
      background: white;
      height: 350px;
      width: 260px;
      box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.08);
      position: fixed;
      bottom: 0;
      margin: 0px 50px;
      border-radius: 2px;
      border: 1px solid #c7c7c7;
  }
  #user{
   background: #36a7ec;
      color: white;
      padding: 8px 10px;
      width: auto;
      display: -webkit-inline-box;
      margin: 8px;
      border-radius: 20px;
  }
  #user2{
   background: #edeff1;
      color: gray;
      padding: 8px 10px;
      width: auto;
      display: -webkit-inline-box;
      margin: 8px;
      border-radius: 20px;
  }
  p{
   margin: 0;
  }
  #typing{
   display: none;
  }
 </style>
</head>
<body>
<a href="logout.php">logout</a>
 <div id="chatBox">
  <div><p id="uStatus">Connecting...</p></div>
  <div id="chating"><div id="chatingIn"></div></div>
  <div><input type="text" name="msg" id="msgField" /></div>
 </div>
 <script type="text/javascript">
  var conn = new WebSocket('ws://localhost:8080');
  conn.onopen = function(e) {
      $('#uStatus').html("<?php echo $name; ?> <span style='color:green;'>[active]</span>");
  };

  conn.onmessage = function(e) {
      $('#chatingIn').append("<p><span id='user2'>"+e.data+"</span></p>");
     $('#chating').animate({scrollTop:$('#chatingIn').height()}, 0);
  };
  $("#msgField").keypress(function(e) {   
  e.preventDefault;
  var key = e.which;
  var msgField = $("#msgField").val();
  if(key == 13) 
    {
      $("#chatingIn").append("<p align='right'><span id='user'>"+msgField+"</span></p>");
      conn.send(msgField);
      $("#msgField").val("");
      $('#chating').animate({scrollTop:$('#chatingIn').height()}, 0); 
   return false;
    }
 });
 </script>
</body>
</html>

here, this file is the chat page of the user .. first we created a php codes to start session and check if user session exist or not and then we added some styles and elements inside the html body and the we added a javascript (using jQuery) to listen and push messages between users.

Step 4
Now, we need to create in app folder > name.php file which is the file who will appear first for users to enter their names before redirecting them to the index.php which is the chat page as we said above.
so, write the following code inside the name.php file :
<?php 
session_start();
error_reporting(E_ALL ^ E_NOTICE);
$namef = $_POST['name'];
$submit = $_POST['sub'];

if (isset($_SESSION['name'])) {
 header("location: index.php");
}

if (isset($submit)) {
 if (!empty($_POST['name'])) {
 $_SESSION['name'] = $namef;
 header("location: index.php");
 }else{
 $error = "Enter your name to start chating";
 }
}
 ?>
<!DOCTYPE html>
<html>
<head>
 <title>hello chating realtime</title>
 <script src="jquery.min.js"></script>
 <style type="text/css">
  body{
   background: #edeff1;
      font-family: sans-serif;
  }
  #nameBox{
  padding: 50px 15px;
     background: #fff;
     box-shadow: 0px 0px 8px #c5c5c5;
     border-radius: 2px;
     width: 400px;
     text-align: center;
     margin: auto;
     margin-top: 10%;
  }
  .inputT{
     padding: 8px 15px;
     outline: none;
     border: none;
     box-shadow: 0px 0px 21px #cad6e2;
     border-radius: 100px;
     width: 300px;
     margin: 15px 0px;
  }
  .inputS{
  border: none;
     background: #399cff;
     color: #fff;
     padding: 8px 15px;
     border-radius: 100px;
     text-decoration: none;
     box-shadow: 0px 0px 21px #3a81c7;
     outline: none; 
  }
  .inputS:hover,.inputS:focus{
  text-decoration: none;
  outline: none; 
  color: #fff;
  cursor: pointer;
  background: #357bc1;
  }
 </style>
</head>
<body>
 <div id="nameBox">
  <form method="post" action="">
   <input class="inputT" type="text" name="name" placeholder="Enter your name" />
   <input class="inputS" type="submit" name="sub" value="Start chating" />
  </form>
  <p style="color: red;"><?php echo $error; ?></p>
 </div>
</body>
</html>
in this file, we at the first lines we are getting the POST "name,sub" fields from the form in the body of this file and then we check if authorized > redirect the user to index.php (The chat page) , and after that we wrote "if statement" to check if submit button clicked or not to authorize the user.. at the end we created some styles and the form elements and like so...

Step 5
 Lets create the logout.php file :
<?php
session_start();
session_destroy();
session_unset();
header("location: name.php");
?>
 this is the logout file contents, its so easy .. only destroying the session and redirect the user to the main page which is name.php (Entering user name).

Step 6
we need to create the server file, but before that we need to create a folder called "bin" in app folder and inside it create chat-server.php and put the following code inside it :
<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;

    require dirname(__DIR__) . '/vendor/autoload.php';

    $server = IoServer::factory(
        new HttpServer(
            new WsServer(
                new Chat()
            )
        ),
        8080
    );

    $server->run();
?>
this is the chat server file which is the important part to run the app.

Step 7
The last thing we need to create is the folder called "src" and inside it another folder called it "MyApp" and inside it create Chat.php class which is the part who responsible to send messages to the listening channel ..
Now, write the following code inside  Chat.php :
<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        $numRecv = count($this->clients) - 1;
        echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
            , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');

        foreach ($this->clients as $client) {
            if ($from !== $client) {
                // The sender is not the receiver, send to each client connected
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);

        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "An error has occurred: {$e->getMessage()}\n";

        $conn->close();
    }
}
?>

Step 8
The last part we need to do is to run our server that we created to open the web sockets connection .. So, open chat-server.php in your browser (just open it and then close it to run the server):
>> your-path/bin/chat-server.php
like : http://localhost/AcruxApp/bin/chat-server.php



That's it :)
after running the server, open your app in the browser and enter a name


and start messaging in a real-time :)



Demo


Source Code
open the link below and click in the green button "clone or download" and then download ZIP :
Download now

Rate the project by giving it a star on GitHub if you loved this tutorial :)