Build Real time Chat Application in PHP Mysql using WebSocket
In this post, we are going to build a simple PHP and Mysql Chat Application using PHP Web Socket Ratchet. If you are looking for How to create Live or Real time chat Application in PHP then you have come on the right place, because in this post we have share you how to create Live Chat Application PHP with WebSockets. In this post, we will create Chat Application in which multiple user can chat with other users.
This is very interesting post on How to create chat App in PHP without using Ajax. In one of our previous post, we have already published tutorial on Chat application in PHP using ajax. But As we have know in Chat system, Ajax based Chat application in PHP is not best solution, this is because Ajax will increases the load on the server. So for this here we have use Ratchet PHP WebSockets for build real-time live chat application in PHP and in this chat app we will store chat data in Mysql database when one user has post chat under this system.
From this tutorial you can learn not only how to make group chat or multi user chat application using Ratchet WebSocket library but also you can also find this solution of one to one or single user or private chat application also. This is because under this post we will combine source code of group chat system and one to one chat application tutorial source code also. So from this single tutorial you can find solution for how to make group chat system and how to build real time one to one chat application also.
Feature of Group Chat Application
Under this Group Chat application using Ratchet Web socket you can get following feature under this tutorial.
- Once single user has send chat message then other connected other user can received chat message using Ratchet client server.
- User online or Offline status will be change after page refresh
Feature of One to One Chat Application
Under this One to one or Single User or Private chat application with Ratchet WebSocket library you can find following feature under this tutorial.
- Send One to One Chat Message in Real-time using Ratchet WebSocket Library
- Display or Hide Unread Message Notification in Real-time using Ratchet WebSocket Library
- Display User Online or Offline Status in Real-time using Ratchet WebSocket Library
What is WebSockets?
WebSockets is a bi-directional and full-duplex which has provide persistent connection from a web browser to our server. So when WebSocket connection has been established in our browser, then it will open connection until client or server has decides to close this connection. So by with this open connection, the user or our server can send or receive chat data at any given time to the each other and it will makes our web programming completely on event driven and not just user started off. The other benefits of this websockets is that, at the same time on single running server, it will connect all connection and it will allowing us to communicate with any number of live connection at the any given time. So this are all benefits of this WebSockets in this Web programming.
Based on this benefits, we have use PHP WebSockets like Ratchet for build Chat Application in PHP and Mysql. Under this post, we will learn you step by step how to build Chat Application in PHP using WebSocket from scratch. Under this PHP Web Development tutorial, you can learn how can we quickly build at Chat App with RatChet using PHP script and Mysql Database.
Database of Chat Application
Before learning chat application, first you need to make tables for store chat application data in Mysql database. So first you need to create tables by run following Sql script you can create chat application tables in you mysql database.
--
-- Database: `chat`
--
-- --------------------------------------------------------
--
-- Table structure for table `chatrooms`
--
CREATE TABLE `chatrooms` (
`id` int(11) NOT NULL,
`userid` int(11) NOT NULL,
`msg` varchar(200) NOT NULL,
`created_on` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `chat_user_table`
--
CREATE TABLE `chat_user_table` (
`user_id` int(11) NOT NULL,
`user_name` varchar(250) NOT NULL,
`user_email` varchar(250) NOT NULL,
`user_password` varchar(100) NOT NULL,
`user_profile` varchar(100) NOT NULL,
`user_status` enum('Disabled','Enable') NOT NULL,
`user_created_on` datetime NOT NULL,
`user_verification_code` varchar(100) NOT NULL,
`user_login_status` enum('Logout','Login') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `chatrooms`
--
ALTER TABLE `chatrooms`
ADD PRIMARY KEY (`id`);
--
-- Indexes for table `chat_user_table`
--
ALTER TABLE `chat_user_table`
ADD PRIMARY KEY (`user_id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `chatrooms`
--
ALTER TABLE `chatrooms`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
--
-- AUTO_INCREMENT for table `chat_user_table`
--
ALTER TABLE `chat_user_table`
MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;
Source Code of PHP Chat Application
Below you can find PHP Chat Application Source code file. database/Database_connection.php This file we will use for make database connection under this chat application.
Below you can find PHP Chat Application Source code file.
database/Database_connection.php
This file we will use for make database connection under this chat application.
<?php
//Database_connection.php
class Database_connection
{
function connect()
{
$connect = new PDO("mysql:host=localhost; dbname=chat", "root", "");
return $connect;
}
}
?>
database/ChatUser.php
This ChatUser.php class file we have use for process user data at server side. Under this class file we have make set and get method for user data and after this we have make method for check user already register or not and lastly we have make insert user data in mysql table.
<?php
//ChatUser.php
class ChatUser
{
private $user_id;
private $user_name;
private $user_email;
private $user_password;
private $user_profile;
private $user_status;
private $user_created_on;
private $user_verification_code;
private $user_login_status;
public $connect;
public function __construct()
{
require_once('Database_connection.php');
$database_object = new Database_connection;
$this->connect = $database_object->connect();
}
function setUserId($user_id)
{
$this->user_id = $user_id;
}
function getUserId()
{
return $this->user_id;
}
function setUserName($user_name)
{
$this->user_name = $user_name;
}
function getUserName()
{
return $this->user_name;
}
function setUserEmail($user_email)
{
$this->user_email = $user_email;
}
function getUserEmail()
{
return $this->user_email;
}
function setUserPassword($user_password)
{
$this->user_password = $user_password;
}
function getUserPassword()
{
return $this->user_password;
}
function setUserProfile($user_profile)
{
$this->user_profile = $user_profile;
}
function getUserProfile()
{
return $this->user_profile;
}
function setUserStatus($user_status)
{
$this->user_status = $user_status;
}
function getUserStatus()
{
return $this->user_status;
}
function setUserCreatedOn($user_created_on)
{
$this->user_created_on = $user_created_on;
}
function getUserCreatedOn()
{
return $this->user_created_on;
}
function setUserVerificationCode($user_verification_code)
{
$this->user_verification_code = $user_verification_code;
}
function getUserVerificationCode()
{
return $this->user_verification_code;
}
function setUserLoginStatus($user_login_status)
{
$this->user_login_status = $user_login_status;
}
function getUserLoginStatus()
{
return $this->user_login_status;
}
function make_avatar($character)
{
$path = "images/". time() . ".png";
$image = imagecreate(200, 200);
$red = rand(0, 255);
$green = rand(0, 255);
$blue = rand(0, 255);
imagecolorallocate($image, $red, $green, $blue);
$textcolor = imagecolorallocate($image, 255,255,255);
$font = dirname(__FILE__) . '/font/arial.ttf';
imagettftext($image, 100, 0, 55, 150, $textcolor, $font, $character);
imagepng($image, $path);
imagedestroy($image);
return $path;
}
function get_user_data_by_email()
{
$query = "
SELECT * FROM chat_user_table
WHERE user_email = :user_email
";
$statement = $this->connect->prepare($query);
$statement->bindParam(':user_email', $this->user_email);
if($statement->execute())
{
$user_data = $statement->fetch(PDO::FETCH_ASSOC);
}
return $user_data;
}
function save_data()
{
$query = "
INSERT INTO chat_user_table (user_name, user_email, user_password, user_profile, user_status, user_created_on, user_verification_code)
VALUES (:user_name, :user_email, :user_password, :user_profile, :user_status, :user_created_on, :user_verification_code)
";
$statement = $this->connect->prepare($query);
$statement->bindParam(':user_name', $this->user_name);
$statement->bindParam(':user_email', $this->user_email);
$statement->bindParam(':user_password', $this->user_password);
$statement->bindParam(':user_profile', $this->user_profile);
$statement->bindParam(':user_status', $this->user_status);
$statement->bindParam(':user_created_on', $this->user_created_on);
$statement->bindParam(':user_verification_code', $this->user_verification_code);
if($statement->execute())
{
return true;
}
else
{
return false;
}
}
function is_valid_email_verification_code()
{
$query = "
SELECT * FROM chat_user_table
WHERE user_verification_code = :user_verification_code
";
$statement = $this->connect->prepare($query);
$statement->bindParam(':user_verification_code', $this->user_verification_code);
$statement->execute();
if($statement->rowCount() > 0)
{
return true;
}
else
{
return false;
}
}
function enable_user_account()
{
$query = "
UPDATE chat_user_table
SET user_status = :user_status
WHERE user_verification_code = :user_verification_code
";
$statement = $this->connect->prepare($query);
$statement->bindParam(':user_status', $this->user_status);
$statement->bindParam(':user_verification_code', $this->user_verification_code);
if($statement->execute())
{
return true;
}
else
{
return false;
}
}
function update_user_login_data()
{
$query = "
UPDATE chat_user_table
SET user_login_status = :user_login_status
WHERE user_id = :user_id
";
$statement = $this->connect->prepare($query);
$statement->bindParam(':user_login_status', $this->user_login_status);
$statement->bindParam(':user_id', $this->user_id);
if($statement->execute())
{
return true;
}
else
{
return false;
}
}
function get_user_data_by_id()
{
$query = "
SELECT * FROM chat_user_table
WHERE user_id = :user_id";
$statement = $this->connect->prepare($query);
$statement->bindParam(':user_id', $this->user_id);
try
{
if($statement->execute())
{
$user_data = $statement->fetch(PDO::FETCH_ASSOC);
}
else
{
$user_data = array();
}
}
catch (Exception $error)
{
echo $error->getMessage();
}
return $user_data;
}
function upload_image($user_profile)
{
$extension = explode('.', $user_profile['name']);
$new_name = rand() . '.' . $extension[1];
$destination = 'images/' . $new_name;
move_uploaded_file($user_profile['tmp_name'], $destination);
return $destination;
}
function update_data()
{
$query = "
UPDATE chat_user_table
SET user_name = :user_name,
user_email = :user_email,
user_password = :user_password,
user_profile = :user_profile
WHERE user_id = :user_id
";
$statement = $this->connect->prepare($query);
$statement->bindParam(':user_name', $this->user_name);
$statement->bindParam(':user_email', $this->user_email);
$statement->bindParam(':user_password', $this->user_password);
$statement->bindParam(':user_profile', $this->user_profile);
$statement->bindParam(':user_id', $this->user_id);
if($statement->execute())
{
return true;
}
else
{
return false;
}
}
function get_user_all_data()
{
$query = "
SELECT * FROM chat_user_table
";
$statement = $this->connect->prepare($query);
$statement->execute();
$data = $statement->fetchAll(PDO::FETCH_ASSOC);
return $data;
}
}
?>
action.php
This file has received ajax request for user logout from chat user application. Under this file, first we have remove session variable value and then after we have remove all session variable and give status value to ajax request in json format.
<?php
//action.php
session_start();
if(isset($_POST['action']) && $_POST['action'] == 'leave')
{
require('database/ChatUser.php');
$user_object = new ChatUser;
$user_object->setUserId($_POST['user_id']);
$user_object->setUserLoginStatus('Logout');
if($user_object->update_user_login_data())
{
unset($_SESSION['user_data']);
session_destroy();
echo json_encode(['status'=>1]);
}
}
?>
src/Chat.php
<?php
//Chat.php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
require dirname(__DIR__) . "/database/ChatUser.php";
require dirname(__DIR__) . "/database/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
echo 'Server Started';
$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);
$chat_object = new \ChatRooms;
$chat_object->setUserId($data['userId']);
$chat_object->setMessage($data['msg']);
$chat_object->setCreatedOn(date("Y-m-d h:i:s"));
$chat_object->save_chat();
$user_object = new \ChatUser;
$user_object->setUserId($data['userId']);
$user_data = $user_object->get_user_data_by_id();
$user_name = $user_data['user_name'];
$data['dt'] = date("d-m-Y h:i:s");
foreach ($this->clients as $client) {
/*if ($from !== $client) {
// The sender is not the receiver, send to each client connected
$client->send($msg);
}*/
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();
}
}
?>
bin/server.php
<?php
//server.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();
?>
composer.json
{
"autoload": {
"psr-4": {
"MyApp\\": "src"
}
},
"require": {
"phpmailer/phpmailer": "^6.2",
"cboden/ratchet": "v0.4"
}
}