In modern web applications, real-time notifications are essential for enhancing user experience. Whether it's for chat applications, order updates, or user interactions, instant notifications keep users engaged. In this tutorial, we will build a real-time notification system in PHP using Ratchet WebSocket.
Why Use WebSockets for Real-Time Notifications?
Traditional polling methods with AJAX requests put a load on the server by continuously checking for updates. WebSockets, on the other hand, enable a persistent connection between the client and the server, allowing instant two-way communication.
Features of Our Notification System:
- Users receive real-time notifications without refreshing the page.
- Unread notification count updates dynamically.
- Notifications appear in a dropdown menu.
- Clicking a notification marks it as read instantly.
Uses of Real-Time Notification System
Real-time notifications can be used in various applications, including:
- E-commerce platforms: Alert users about order status updates, flash sales, and price drops.
- Social media networks: Notify users about likes, comments, shares, and friend requests.
- Banking and finance apps: Inform users about transactions, payment reminders, and security alerts.
- Healthcare systems: Notify doctors and patients about appointment confirmations, medical reports, and prescription updates.
- Customer support systems: Provide instant responses, ticket updates, and live chat notifications.
- Project management tools: Alert team members about task assignments, deadlines, and project updates.
Benefits of a Real-Time Notification System
- Improved user engagement: Keeps users informed and active on the platform.
- Faster response times: Enables instant communication and quick decision-making.
- Better user experience: Eliminates the need for page refreshes, providing seamless interaction.
- Efficient server resource utilization: Reduces server load compared to traditional polling methods.
- Enhanced security: Immediate alerts for login attempts, unauthorized access, and account changes.
Examples of Real-Time Notification Systems
- Facebook, Twitter, Instagram: Social media notifications for likes, comments, and mentions.
- WhatsApp, Slack, Microsoft Teams: Instant messaging and chat notifications.
- Amazon, Flipkart, eBay: Order updates, shipment tracking, and product promotions.
- Gmail, Outlook, Yahoo Mail: Email notifications for new messages.
- Trello, Asana, Jira: Task management and project update notifications.
Setting Up Ratchet WebSocket in PHP
Step 1: Install Ratchet WebSocket Library
First, install Ratchet using Composer:
composer require cboden/ratchet
Step 2: Create the WebSocket Server (server.php)
Create a server.php file to handle WebSocket connections and notifications.
<?php
require 'vendor/autoload.php';
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class NotificationServer implements MessageComponentInterface {
protected $clients;
private $pdo;
public function __construct(){
$this->clients = new \SplObjectStorage;
$this->pdo = new PDO("mysql:host=localhost;dbname=testing", "root", "1234567890");
}
public function onOpen(ConnectionInterface $conn){
$this->clients->attach($conn);
echo "New connection! - ({$conn->resourceId})\n";
$this->sendNotifications($conn);
}
public function onMessage(ConnectionInterface $from, $msg){
$data = json_decode($msg, true);
if(isset($data['type']) && $data['type'] === 'new_comment'){
$statement = $this->pdo->prepare("INSERT INTO comments (comment_subject, comment_text, comment_status) VALUES (?, ?, 0)");
$statement->execute([$data['subject'], $data['comment']]);
$this->broadcastNotifications();
}
if(isset($data['type']) && $data['type'] === 'mark_as_read'){
$this->markNotificationAsRead($data['comment_id']);
$this->broadcastNotifications(); // Refresh for all users
}
}
public function onClose(ConnectionInterface $conn){
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e){
echo "An error occurred: {$e->getMessage()}\n";
$conn->close();
}
private function broadcastNotifications()
{
foreach($this->clients as $client){
$this->sendNotifications($client);
}
}
private function markNotificationAsRead($commentId){
$statement = $this->pdo->prepare("UPDATE comments SET comment_status = 1 WHERE comment_id = ?");
$statement->execute([$commentId]);
}
private function sendNotifications(ConnectionInterface $conn){
$statement = $this->pdo->query("SELECT * FROM comments ORDER BY comment_id DESC LIMIT 5");
$notifications = $statement->fetchAll(PDO::FETCH_ASSOC);
$statement = $this->pdo->query("SELECT COUNT(*) AS unread_count FROM comments WHERE comment_status = 0");
$unreadCount = $statement->fetch(PDO::FETCH_ASSOC)["unread_count"];
$response = [
'type' => 'notification',
'notifications' => $notifications,
'unread_count' => $unreadCount
];
$conn->send(json_encode($response));
}
}
// Start the WebSocket server
$server = IoServer::factory(
new HttpServer(
new WsServer(
new NotificationServer()
)
),
8080
);
echo "WebSocket server started on port 8080\n";
$server->run();
?>
Step 3: Send Comment (add_comment.php)
Now for Subject Comment data to Websocket server, we have to create add_comment.php file and under this file, We have to write following HTML and JavaScript code for submit comment form data to Ratchet Websocket server.
add_comment.php
<!DOCTYPE html>
<html>
<head>
<title>Add Comment</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container mt-5">
<h2 class="text-center mb-4">Add a Comment</h2>
<div class="card shadow-sm p-4">
<form id="commentForm" onsubmit="event.preventDefault(); sendComment(); ">
<div class="mb-3">
<label class="form-label">Enter Subject</label>
<input type="text" class="form-control" id="subject" required />
</div>
<div class="mb-3">
<label class="form-label">Enter Comment</label>
<textarea class="form-control" id="comment" rows="3" required></textarea>
</div>
<button type="submit" class="btn btn-primary w-100">Post Comment</button>
</form>
</div>
<script>
var ws = new WebSocket("ws://localhost:8080");
function sendComment()
{
var subject = document.getElementById('subject').value;
var comment = document.getElementById('comment').value;
if(subject && comment){
var data = {
type : "new_comment",
subject : subject,
comment : comment
};
ws.send(JSON.stringify(data));
document.getElementById("commentForm").reset();
alert("Comment Added!");
} else {
alert("Both fields are required!");
}
}
</script>
</body>
</html>
Step 4 : Create MySQL Table
This is dynamic Real-Time Notification System using Ratchet Websocket, So for store notification data we have to create Comments table in our MySQL database. So for this We have to run following SQL script for create comments table in MySQL database.
CREATE TABLE `comments` (
`comment_id` int NOT NULL AUTO_INCREMENT,
`comment_subject` varchar(250) NOT NULL,
`comment_text` text NOT NULL,
`comment_status` int NOT NULL DEFAULT '0',
PRIMARY KEY (`comment_id`)
) ENGINE=InnoDB;
Step 5 : Display Notification
For Display Real-time notification to connected user, we have to create notifications.php file. Under this file, we have to write HTML & JavaScript code for display Real-time notification data on web page to connected user.
notifications.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Real-Time Notifications</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container mt-5">
<h2 class="text-center mb-4">Real-Time Notifications</h2>
<div class="card shadow-sm p-4">
<div class="text-end">
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" id="notificationDropdown" data-bs-toggle="dropdown" aria-expanded="false">
Notifications <span id="unreadCount" class="badge bg-danger">0</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" id="notificationList">
<li><a class="dropdown-item text-center">No new notifications</a></li>
</ul>
</div>
</div>
</div>
<script>
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(){
console.log('WebSocket Connected!');
};
conn.onmessage = function(event){
var data = JSON.parse(event.data);
if(data.type === 'notification'){
updateNotificationDropdown(data.notifications);
}
};
function updateNotificationDropdown(notifications){
var notificationList = document.getElementById('notificationList');
var unreadBadge = document.getElementById('unreadCount');
notificationList.innerHTML = '';
if(notifications.length === 0){
notificationList.innerHTML = `<li><a class="dropdown-item text-center">No new notifications</a></li>`;
unreadBadge.style.display = 'none';
return;
}
let count = 0;
notifications.forEach(function(notification){
let li = document.createElement('li');
let a = document.createElement('a');
a.className = 'dropdown-item';
a.href = '#';
a.innerHTML = `<strong>${notification.comment_subject}</strong>:${notification.comment_text}`;
if(notification.comment_status == 0){
console.log('test');
a.style.fontWeight = 'bold';
count++;
}
// Mark as read on click
a.onclick = function(){
markAsRead(notification.comment_id);
};
li.appendChild(a);
notificationList.appendChild(li);
});
unreadBadge.textContent = count;
unreadBadge.style.display = count > 0 ? "inline" : "none";
}
function markAsRead(commentId){
conn.send(JSON.stringify({ type : "mark_as_read", comment_id : commentId }));
}
</script>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
Run the WebSocket server using:
php server.php
Output
In below Screenshot you can find the output of this Real-time Notification system application.
Download Source Code
If you want to download complete source code of PHP MySQL Real-time Notification System using Ratchet Websocket, then below you can find source code download link.