


How to use PHP to implement real-time notification system PHP message push and subscription
Jul 25, 2025 pm 05:45 PMTo implement a real-time notification system, the core is to establish a long connection between the server and the client. 1. Use the WebSocket protocol to realize two-way real-time communication, PHP can be implemented through Ratchet and other libraries; 2. The front-end uses JavaScript to establish connections and process messages; 3. Optional message queues such as Redis Pub/Sub decoupling high concurrency pressure; 4. Passing tokens through URL parameters to achieve user identity authentication; 5. Optimizing performance can be achieved through Swoole, message compression, connection pooling and other means; 6. The front-end realizes the disconnection mechanism, and uses an exponential backoff algorithm to control the reconnect frequency.
PHP implements a real-time notification system. Simply put, it is to enable your website or application to know new news like WeChat. The core is to establish a long connection between the server and the client, so that the server can push messages to the client at any time.

Solution
To implement PHP real-time notification system, it mainly relies on the following technical points:
-
WebSocket : This is the key to real-time communication. The WebSocket protocol allows servers and clients to establish persistent connections, and data can be transmitted in real time in both directions. PHP itself does not directly support WebSocket, and requires extensions or third-party libraries.
Message queue (optional) : When the concurrency is large, the message queue can decouple the sending and receiving of messages to avoid excessive server pressure. Commonly used message queue services include RabbitMQ, Redis Pub/Sub, etc.
-
Front-end technology : The front-end needs to use JavaScript to establish a WebSocket connection and process the received messages.
Specific steps:
Choose WebSocket Server: The more popular choice is Ratchet. Ratchet is a pure PHP implementation WebSocket library, which is easy to use. You can also choose Socket.IO for Node.js, but this means you need to maintain both PHP and Node.js environments.
Install Ratchet (if selected): Install through Composer:
composer require cboden/ratchet
-
Write WebSocket server-side code (PHP):
<?php use Ratchet\Server\IoServer; use Ratchet\Http\HttpServer; use Ratchet\WebSocket\WsServer; use MyApp\MessageHandler; require __DIR__ . '/vendor/autoload.php'; // Create a class that handles messages MessageHandler implements Ratchet\MessageComponentInterface { protected $clients; public function __construct() { $this->clients = new \SplObjectStorage; } public function onOpen(\Ratchet\ConnectionInterface $conn) { $this->clients->attach($conn); echo "New connection! ({$conn->resourceId})\n"; } public function onMessage(\Ratchet\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(\Ratchet\ConnectionInterface $conn) { $this->clients->detach($conn); echo "Connection {$conn->resourceId} has disconnected\n"; } public function onError(\Ratchet\ConnectionInterface $conn, \Exception $e) { echo "An error has occurred: {$e->getMessage()}\n"; $conn->close(); } } // Start WebSocket server $server = IoServer::factory( new HttpServer( new WsServer( new MessageHandler() ) ), 8080 // Listen to port); $server->run();
Write front-end code (JavaScript):
var conn = new WebSocket('ws://localhost:8080'); // Connect to WebSocket server conn.onopen = function(e) { console.log("Connection established!"); }; conn.onmessage = function(e) { console.log(e.data); // Process the received message// Display the message on the page, for example: var message = document.createElement("p"); message.textContent = e.data; document.body.appendChild(message); }; // Send message function sendMessage() { var messageInput = document.getElementById("messageInput"); var message = messageInput.value; conn.send(message); messageInput.value = ""; // Clear the input box} conn.onclose = function(e) { console.log("Connection closed."); };
Integrated message queue (optional): If you need to handle high concurrency, you can send messages to the message queue first, and then a specialized process reads the messages from the message queue and pushes them to the client. For example, use Redis's
PUBLISH
andSUBSCRIBE
commands.
How to handle user authentication and authorization?
Authentication and authorization are important components of the real-time notification system. WebSocket itself does not provide an authentication mechanism and needs to be implemented by itself. A common practice is to pass the token through the URL parameter when the WebSocket connection is established, and then verify the validity of the token on the server side.
front end:
// Get the user token (assuming it has been stored in localStorage) const token = localStorage.getItem('userToken'); var conn = new WebSocket('ws://localhost:8080?token=' token);
Backend (PHP):
public function onOpen(\Ratchet\ConnectionInterface $conn) { $uri = $conn->httpRequest->getUri(); parse_str($uri->getQuery(), $parameters); $token = $parameters['token'] ?? null; // Verify token if (!$this->isValidToken($token)) { $conn->close(); // Close the connection return; } // Get the user ID or other user information and store it in the connection object $userId = $this->getUserIdByToken($token); $conn->userId = $userId; // Store user ID $this->clients->attach($conn); echo "New connection! User ID: {$userId} ({$conn->resourceId})\n"; } private function isValidToken($token) { // Implement token verification logic, such as querying the database // Return true to indicate that the token is valid, otherwise return false // ... return true; // Example, always return true } private function getUserIdByToken($token) { // Get the user ID based on the token, for example querying the database // ... return 123; // Example, return fixed user ID }
After verification is passed, the user ID or other user information can be stored in the connection object $conn
for easier subsequent use. When sending a message, it can be filtered according to the user ID and sent to only specific users.
How to optimize the performance of PHP real-time notification system?
Performance optimization is the key to any real-time system. Here are some optimization measures that can be considered:
Using a high-performance WebSocket server: Ratchet is a good choice, but if you have higher performance requirements, you can consider Swoole extensions. Swoole is a PHP extension based on C language, providing asynchronous and multi-threaded network programming capabilities, and its performance is much higher than that of traditional PHP environments.
Use message queue: Message queue can decouple the sending and receiving of messages, avoiding excessive server pressure.
Optimize database query: Avoid frequent database query on the WebSocket server side. Commonly used data can be cached into memory, for example using Redis.
Compressed messages: Compress sent messages to reduce the bandwidth of network transmission.
Connection pool: If you need to connect to a database or other service, you can use the connection pool to reuse the connection to avoid the overhead of frequent creation and destruction of connections.
Load balancing: When the concurrency is large, you can use a load balancer to distribute requests to multiple servers to improve the overall throughput of the system.
Heartbeat detection: send heartbeat packets regularly to detect whether the client is still online. If the client does not respond for a long time, close the connection and free the resource.
How to deal with disconnection and reconnection?
Network instability is common, so disconnection and reconnection are issues that must be considered in real-time notification systems.
front end:
conn.onclose = function(e) { console.log("Connection closed. Reconnecting in 5 seconds..."); setTimeout(function() { // Reconnect to the WebSocket server conn = new WebSocket('ws://localhost:8080?token=' token); //Re-register the event handler function (onopen, onmessage, onerror) // ... }, 5000); // Reconnect after 5 seconds};
-
Backend (PHP):
The backend does not need to do special processing, because after the WebSocket connection is disconnected, the server will automatically trigger the
onClose
event, which can clean up resources in this event. What is important is that the front end is responsible for reconnection.
In practical applications, an exponential backoff algorithm can be used to control the frequency of reconnection to avoid frequent reconnection when the network is in poor condition.
The above is the detailed content of How to use PHP to implement real-time notification system PHP message push and subscription. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

PHPisstillrelevantinmodernenterpriseenvironments.1.ModernPHP(7.xand8.x)offersperformancegains,stricttyping,JITcompilation,andmodernsyntax,makingitsuitableforlarge-scaleapplications.2.PHPintegrateseffectivelyinhybridarchitectures,servingasanAPIgateway

To build a flexible PHP microservice, you need to use RabbitMQ to achieve asynchronous communication, 1. Decouple the service through message queues to avoid cascade failures; 2. Configure persistent queues, persistent messages, release confirmation and manual ACK to ensure reliability; 3. Use exponential backoff retry, TTL and dead letter queue security processing failures; 4. Use tools such as supervisord to protect consumer processes and enable heartbeat mechanisms to ensure service health; and ultimately realize the ability of the system to continuously operate in failures.

Avoid N 1 query problems, reduce the number of database queries by loading associated data in advance; 2. Select only the required fields to avoid loading complete entities to save memory and bandwidth; 3. Use cache strategies reasonably, such as Doctrine's secondary cache or Redis cache high-frequency query results; 4. Optimize the entity life cycle and call clear() regularly to free up memory to prevent memory overflow; 5. Ensure that the database index exists and analyze the generated SQL statements to avoid inefficient queries; 6. Disable automatic change tracking in scenarios where changes are not required, and use arrays or lightweight modes to improve performance. Correct use of ORM requires combining SQL monitoring, caching, batch processing and appropriate optimization to ensure application performance while maintaining development efficiency.

Using the correct PHP basic image and configuring a secure, performance-optimized Docker environment is the key to achieving production ready. 1. Select php:8.3-fpm-alpine as the basic image to reduce the attack surface and improve performance; 2. Disable dangerous functions through custom php.ini, turn off error display, and enable Opcache and JIT to enhance security and performance; 3. Use Nginx as the reverse proxy to restrict access to sensitive files and correctly forward PHP requests to PHP-FPM; 4. Use multi-stage optimization images to remove development dependencies, and set up non-root users to run containers; 5. Optional Supervisord to manage multiple processes such as cron; 6. Verify that no sensitive information leakage before deployment

ReadonlypropertiesinPHP8.2canonlybeassignedonceintheconstructororatdeclarationandcannotbemodifiedafterward,enforcingimmutabilityatthelanguagelevel.2.Toachievedeepimmutability,wrapmutabletypeslikearraysinArrayObjectorusecustomimmutablecollectionssucha

PHP's garbage collection mechanism is based on reference counting, but circular references need to be processed by a periodic circular garbage collector; 1. Reference count releases memory immediately when there is no reference to the variable; 2. Reference reference causes memory to be unable to be automatically released, and it depends on GC to detect and clean it; 3. GC is triggered when the "possible root" zval reaches the threshold or manually calls gc_collect_cycles(); 4. Long-term running PHP applications should monitor gc_status() and call gc_collect_cycles() in time to avoid memory leakage; 5. Best practices include avoiding circular references, using gc_disable() to optimize performance key areas, and dereference objects through the ORM's clear() method.

Bref enables PHP developers to build scalable, cost-effective applications without managing servers. 1.Bref brings PHP to AWSLambda by providing an optimized PHP runtime layer, supports PHP8.3 and other versions, and seamlessly integrates with frameworks such as Laravel and Symfony; 2. The deployment steps include: installing Bref using Composer, configuring serverless.yml to define functions and events, such as HTTP endpoints and Artisan commands; 3. Execute serverlessdeploy command to complete the deployment, automatically configure APIGateway and generate access URLs; 4. For Lambda restrictions, Bref provides solutions.

It is recommended to use the in keyword to check whether a key exists in the dictionary, because it is concise, efficient and highly readable; 2. It is not recommended to use the get() method to determine whether the key exists, because it will be misjudged when the key exists but the value is None; 3. You can use the keys() method, but it is redundant, because in defaults to check the key; 4. When you need to get a value and the expected key usually exists, you can use try-except to catch the KeyError exception. The most recommended method is to use the in keyword, which is both safe and efficient, and is not affected by the value of None, which is suitable for most scenarios.
