Chat application in PHP & MySQL using Ratchet Library (ok)

C:\xampp\htdocs\chatroom\composer.json

{
  "autoload":
  {
    "psr-4":
    {
      "MyApp\\": "src"
    }
  },
  "require":
  {
    "cboden/ratchet": "^0.4.3"
  }
}

C:\xampp\htdocs\chatroom\index.php

<!DOCTYPE html>
<html>
<head>
  <title>Chat application in php using web scocket programming</title>
  <!-- Latest compiled and minified CSS & JS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
  <div class="container">
    <h2 class="text-center" style="margin-top: 5px; padding-top: 0;">Chat application in PHP & MySQL using Ratchet Library</h2>
    <hr>
    <?php 
			if(isset($_POST['join'])) {
				session_start();
				require("db/users.php");
				$objUser = new users;
				$objUser->setEmail($_POST['email']);
				$objUser->setName($_POST['uname']);
				$objUser->setLoginStatus(1);
			 	$objUser->setLastLogin(date('Y-m-d h:i:s'));
			 	$userData = $objUser->getUserByEmail();
			 	if(is_array($userData) && count($userData)>0) {
			 		$objUser->setId($userData['id']);
			 		if($objUser->updateLoginStatus()) {
			 			echo "User login..";
			 			$_SESSION['user'][$userData['id']] = $userData;
			 			header("location: chatroom.php");
			 		} else {
			 			echo "Failed to login.";
			 		}
			 	} else {
				 	if($objUser->save()) {
				 		$lastId = $objUser->dbConn->lastInsertId();
				 		$objUser->setId($lastId);
						$_SESSION['user'][$lastId] = [ 
							'id' => $objUser->getId(), 
							'name' => $objUser->getName(), 
							'email'=> $objUser->getEmail(), 
							'login_status'=>$objUser->getLoginStatus(), 
							'last_login'=> $objUser->getLastLogin() 
						];
				 		echo "User Registred..";
				 		header("location: chatroom.php");
				 	} else {
				 		echo "Failed..";
				 	}
				 }
			}
		 ?>
    <div class="row join-room">
      <div class="col-md-6 col-md-offset-3">
        <form id="join-room-frm" role="form" method="post" action="" class="form-horizontal">
          <div class="form-group">
            <div class="input-group">
              <div class="input-group-addon addon-diff-color">
                <span class="glyphicon glyphicon-user"></span>
              </div>
              <input type="text" class="form-control" id="uname" name="uname" placeholder="Enter Name">
            </div>
          </div>
          <div class="form-group">
            <div class="input-group">
              <div class="input-group-addon addon-diff-color">
                <span class="glyphicon glyphicon-envelope"></span>
              </div>
              <input type="email" class="form-control" id="email" name="email" placeholder="Enter Email Address" value="">
            </div>
          </div>
          <div class="form-group">
            <input type="submit" value="JOIN CHATROOM" class="btn btn-success btn-block" id="join" name="join">
          </div>
        </form>
      </div>
    </div>
  </div>
</body>
</html>

C:\xampp\htdocs\chatroom\chatroom.php

<!DOCTYPE html>
<html>
<head>
  <title>Chat application in php using web scocket programming</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"" crossorigin=" anonymous">
  <script src="https://code.jquery.com/jquery.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
  <style type="text/css">
  #messages {
    height: 200px;
    background: whitesmoke;
    overflow: auto;
  }
  #chat-room-frm {
    margin-top: 10px;
  }
  </style>
</head>
<body>
  <div class="container">
    <h2 class="text-center" style="margin-top: 5px; padding-top: 0;">Chat application in PHP & MySQL using Ratchet Library</h2>
    <hr>
    <div class="row">
      <div class="col-md-4">
        <?php 
					session_start();
					if(!isset($_SESSION['user'])) {
						header("location: index.php");
					}
					require("db/users.php");
					require("db/chatrooms.php");
					$objChatroom = new chatrooms;
					$chatrooms   = $objChatroom->getAllChatRooms();
					$objUser = new users;
					$users   = $objUser->getAllUsers();
				 ?>
        <table class="table table-striped">
          <thead>
            <tr>
              <td>
                <?php 
									foreach ($_SESSION['user'] as $key => $user) {
										$userId = $key;
										echo '<input type="hidden" name="userId" id="userId" value="'.$key.'">';
										echo "<div>".$user['name']."</div>";
										echo "<div>".$user['email']."</div>";
									}
								 ?>
              </td>
              <td align="right" colspan="2">
                <input type="button" class="btn btn-warning" id="leave-chat" name="leave-chat" value="Leave">
              </td>
            </tr>
            <tr>
              <th colspan="3">Users</th>
            </tr>
          </thead>
          <tbody>
            <?php 
							foreach ($users as $key => $user) {
								$color = 'color: red';
								if($user['login_status'] == 1) {
									$color = 'color: green';
								}
								if(!isset($_SESSION['user'][$user['id']])) {
								echo "<tr><td>".$user['name']."</td>";
								echo "<td><span class='glyphicon glyphicon-globe' style='".$color."'></span></td>";
								echo "<td>".$user['last_login']."</td></tr>";
								}
							}
						 ?>
          </tbody>
        </table>
      </div>
      <div class="col-md-8">
        <div id="messages">
          <table id="chats" class="table table-striped">
            <thead>
              <tr>
                <th colspan="4" scope="col"><strong>Chat Room</strong></th>
              </tr>
            </thead>
            <tbody>
              <?php 
					  		foreach ($chatrooms as $key => $chatroom) {
					  			if($userId == $chatroom['userid']) {
					  				$from = "Me";
					  			} else {
					  				$from = $chatroom['name'];
					  			}
					  			echo '<tr><td valign="top"><div><strong>'.$from.'</strong></div><div>'.$chatroom['msg'].'</div><td align="right" valign="top">'.date("d/m/Y h:i:s A", strtotime($chatroom['created_on'])).'</td></tr>';
					  		}
					  	 ?>
            </tbody>
          </table>
        </div>
        <form id="chat-room-frm" method="post" action="">
          <div class="form-group">
            <textarea class="form-control" id="msg" name="msg" placeholder="Enter Message"></textarea>
          </div>
          <div class="form-group">
            <input type="button" value="Send" class="btn btn-success btn-block" id="send" name="send">
          </div>
        </form>
      </div>
    </div>
  </div>
</body>
<script type="text/javascript">
$(document).ready(function() {
  var conn = new WebSocket('ws://localhost:8080');
  conn.onopen = function(e) {
    console.log("Connection established!");
  };
  conn.onmessage = function(e) {
    console.log(e.data);
    var data = JSON.parse(e.data);
    var row = '<tr><td valign="top"><div><strong>' + data.from + '</strong></div><div>' + data.msg + '</div><td align="right" valign="top">' + data.dt + '</td></tr>';
    $('#chats > tbody').prepend(row);
  };
  conn.onclose = function(e) {
    console.log("Connection Closed!");
  }
  $("#send").click(function() {
    var userId = $("#userId").val();
    var msg = $("#msg").val();
    var data = {
      userId: userId,
      msg: msg
    };
    conn.send(JSON.stringify(data));
    $("#msg").val("");
  });
  $("#leave-chat").click(function() {
    var userId = $("#userId").val();
    $.ajax({
      url: "action.php",
      method: "post",
      data: "userId=" + userId + "&action=leave"
    }).done(function(result) {
      var data = JSON.parse(result);
      if (data.status == 1) {
        conn.close();
        location = "index.php";
      } else {
        console.log(data.msg);
      }
    });
  })
})
</script>
</html>

C:\xampp\htdocs\chatroom\action.php

<?php 
	session_start();
	if(isset($_POST['action']) && $_POST['action'] == 'leave') {
		require("db/users.php");
		$objUser = new users;
		$objUser->setLoginStatus(0);
	 	$objUser->setLastLogin(date('Y-m-d h:i:s'));
	 	$objUser->setId($_POST['userId']);
	 	if($objUser->updateLoginStatus()) {
	 		unset($_SESSION['user']);
	 		session_destroy();
	 		echo json_encode(['status'=>1, 'msg'=>"Logout.."]);
	 	} else {
	 		echo json_encode(['status'=>0, 'msg'=>"Somthing went wrong.."]);
	 	}
	}
 ?>

C:\xampp\htdocs\chatroom\src\Chat.php

<?php
namespace MyApp;
use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;
require "../db/users.php";
require "../db/chatrooms.php";
class Chat implements MessageComponentInterface {
  protected $clients;
  public function __construct() {
    $this->clients = new \SplObjectStorage;
    echo "Server Started.";
  }
  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');
    $data        = json_decode($msg, true);
    $objChatroom = new \chatrooms;
    $objChatroom->setUserId($data['userId']);
    $objChatroom->setMsg($data['msg']);
    $objChatroom->setCreatedOn(date("Y-m-d h:i:s"));
    if ($objChatroom->saveChatRoom()) {
      $objUser = new \users;
      $objUser->setId($data['userId']);
      $user         = $objUser->getUserById();
      $data['from'] = $user['name'];
      $data['msg']  = $data['msg'];
      $data['dt']   = date("d-m-Y h:i:s");
    }
    foreach ($this->clients as $client) {
      if ($from == $client) {
        $data['from'] = "Me";
      } else {
        $data['from'] = $user['name'];
      }
      $client->send(json_encode($data));
    }
  }
  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();
  }
}

C:\xampp\htdocs\chatroom\db\chatrooms.php

<?php
class chatrooms {
  private $id;
  private $userId;
  private $msg;
  private $createdOn;
  protected $dbConn;
  function setId($id) {$this->id = $id;}
  function getId() {return $this->id;}
  function setUserId($userId) {$this->userId = $userId;}
  function getUserId() {return $this->userId;}
  function setMsg($msg) {$this->msg = $msg;}
  function getMsg() {return $this->msg;}
  function setCreatedOn($createdOn) {$this->createdOn = $createdOn;}
  function getCreatedOn() {return $this->createdOn;}
  public function __construct() {
    require_once 'DbConnect.php';
    $db           = new DbConnect();
    $this->dbConn = $db->connect();
  }
  public function saveChatRoom() {
    $stmt = $this->dbConn->prepare('INSERT INTO chatrooms VALUES(null, :userid, :msg, :createdOn)');
    $stmt->bindParam(':userid', $this->userId);
    $stmt->bindParam(':msg', $this->msg);
    $stmt->bindParam(':createdOn', $this->createdOn);
    if ($stmt->execute()) {
      return true;
    } else {
      return false;
    }
  }
  public function getAllChatRooms() {
    $stmt = $this->dbConn->prepare("SELECT c.*, u.name FROM chatrooms c JOIN users u ON(c.userid = u.id) ORDER BY c.id DESC");
    $stmt->execute();
    $chatrooms = $stmt->fetchAll(PDO::FETCH_ASSOC);
    return $chatrooms;
  }
}
?>

C:\xampp\htdocs\chatroom\db\DbConnect.php

<?php
class DbConnect {
  private $host   = 'localhost';
  private $dbName = 'websocket';
  private $user   = 'root';
  private $pass   = '';
  public function connect() {
    try {
      $conn = new PDO('mysql:host=' . $this->host . '; dbname=' . $this->dbName, $this->user, $this->pass);
      $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      return $conn;
    } catch (PDOException $e) {
      echo 'Database Error: ' . $e->getMessage();
    }
  }
}
?>

C:\xampp\htdocs\chatroom\db\users.php

<?php 
	class users {
		private $id;
		private $name;
		private $email;
		private $loginStatus;
		private $lastLogin;
		public $dbConn;
		function setId($id) { $this->id = $id; }
		function getId() { return $this->id; }
		function setName($name) { $this->name = $name; }
		function getName() { return $this->name; }
		function setEmail($email) { $this->email = $email; }
		function getEmail() { return $this->email; }
		function setLoginStatus($loginStatus) { $this->loginStatus = $loginStatus; }
		function getLoginStatus() { return $this->loginStatus; }
		function setLastLogin($lastLogin) { $this->lastLogin = $lastLogin; }
		function getLastLogin() { return $this->lastLogin; }
		public function __construct() {
			require_once("DbConnect.php");
			$db = new DbConnect();
			$this->dbConn = $db->connect();
		}
		public function save() {
			$sql = "INSERT INTO `users`(`id`, `name`, `email`, `login_status`, `last_login`) VALUES (null, :name, :email, :loginStatus, :lastLogin)";
			$stmt = $this->dbConn->prepare($sql);
			$stmt->bindParam(":name", $this->name);
			$stmt->bindParam(":email", $this->email);
			$stmt->bindParam(":loginStatus", $this->loginStatus);
			$stmt->bindParam(":lastLogin", $this->lastLogin);
			try {
				if($stmt->execute()) {
					return true;
				} else {
					return false;
				}
			} catch (Exception $e) {
				echo $e->getMessage();
			}
		}
		public function getUserByEmail() {
			$stmt = $this->dbConn->prepare('SELECT * FROM users WHERE email = :email');
			$stmt->bindParam(':email', $this->email);
			try {
				if($stmt->execute()) {
					$user = $stmt->fetch(PDO::FETCH_ASSOC);
				}
			} catch (Exception $e) {
				echo $e->getMessage();
			}
			return $user;
		}
		public function getUserById() {
			$stmt = $this->dbConn->prepare('SELECT * FROM users WHERE id = :id');
			$stmt->bindParam(':id', $this->id);
			try {
				if($stmt->execute()) {
					$user = $stmt->fetch(PDO::FETCH_ASSOC);
				}
			} catch (Exception $e) {
				echo $e->getMessage();
			}
			return $user;
		}
		public function updateLoginStatus() {
			$stmt = $this->dbConn->prepare('UPDATE users SET login_status = :loginStatus, last_login = :lastLogin WHERE id = :id');
			$stmt->bindParam(':loginStatus', $this->loginStatus);
			$stmt->bindParam(':lastLogin', $this->lastLogin);
			$stmt->bindParam(':id', $this->id);
			try {
				if($stmt->execute()) {
					return true;
				} else {
					return false;
				}
			} catch (Exception $e) {
				echo $e->getMessage();
			}
		}
		public function getAllUsers() {
			$stmt = $this->dbConn->prepare("SELECT * FROM users");
			$stmt->execute();
			$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
			return $users;
		}
	}

C:\xampp\htdocs\chatroom\bin\server.php

<?php
use MyApp\Chat;
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
  new HttpServer(
    new WsServer(
      new Chat()
    )
  ),
  8080
);
$server->run();

Last updated