I am developing a mobile application and I would like to send notifications to the relevant users when there is a change in a database table. To achieve this, I have tried to create a WebSocket server that listens to the database and notifies the frontend, which then sends notifications even when the application is closed. However, my frontend is unable to connect to the WebSocket server. Here is the error:
LOG WebSocket error: {“isTrusted”: false, “message”: “The operation couldn’t be completed. Connection refused”}
LOG WebSocket is closed.
I am new to mobile development and I have never created a socket server before.
<?php
require __DIR__ . '/vendor/autoload.php';
use RatchetMessageComponentInterface;
use RatchetConnectionInterface;
use ReactEventLoopLoop;
use RatchetApp;
class DatabaseWatcher implements MessageComponentInterface
{
protected $clients;
protected $lastMaxId;
public function __construct()
{
$this->clients = new SplObjectStorage;
$this->lastMaxId = $this->getMaxId();
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn, ['ref_restaurant' => null]);
echo "New connection! ({$conn->resourceId})n";
}
public function onMessage(ConnectionInterface $from, $msg)
{
$data = json_decode($msg, true);
if (isset($data['ref_restaurant'])) {
$this->clients[$from]['ref_restaurant'] = $data['ref_restaurant'];
echo "Client {$from->resourceId} set ref_restaurant to {$data['ref_restaurant']}n";
}
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnectedn";
}
public function onError(ConnectionInterface $conn, Exception $e)
{
echo "An error has occurred: {$e->getMessage()}n";
$conn->close();
}
public function getMaxId()
{
try {
$pdo = new PDO('mysql:host=193.203.168.77;dbname=u440859155_db_yumeats', 'u440859155_yumeats', 'YumEats2024@');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT MAX(id) AS max_id FROM orders');
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result['max_id'] ?? 0;
} catch (PDOException $e) {
echo "Database error: " . $e->getMessage() . "n";
return 0;
}
}
public function checkDatabase()
{
try {
$pdo = new PDO('mysql:host=193.203.168.77;dbname=u440859155_db_yumeats', 'u440859155_yumeats', 'YumEats2024@');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT * FROM orders WHERE id > :lastMaxId');
$stmt->execute(['lastMaxId' => $this->lastMaxId]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($rows)) {
$this->lastMaxId = max(array_column($rows, 'id'));
echo "New entries found:n";
print_r($rows); // Log the new entries
foreach ($this->clients as $client) {
$clientRestaurant = $this->clients[$client]['ref_restaurant'];
$filteredRows = array_filter($rows, function ($row) use ($clientRestaurant) {
return $row['ref_restaurant'] === $clientRestaurant;
});
if (!empty($filteredRows)) {
$client->send(json_encode($filteredRows));
}
}
}
} catch (PDOException $e) {
echo "Database error: " . $e->getMessage() . "n";
}
}
}
$app = new RatchetApp('0.0.0.0', 8080);
$loop = Loop::get();
$databaseWatcher = new DatabaseWatcher();
$loop->addPeriodicTimer(1, function () use ($databaseWatcher) {
$databaseWatcher->checkDatabase();
});
$app->route('/database-watcher', $databaseWatcher, ['*']);
$app->run();
const ws = useRef(null);
const initializeWebSocket = (refRestaurant) => {
ws.current = new WebSocket('ws://localhost:8080/database-watcher');
ws.current.onopen = () => {
console.log('WebSocket is connected.');
ws.current.send(JSON.stringify({ ref_restaurant: refRestaurant }));
};
ws.current.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Received data:', data);
setOrdersAndClients(prevOrders => [...prevOrders, ...data]);
Alert.alert(
"Nouvelle commande",
"Une nouvelle commande a été reçue.",
[{ text: "OK" }]
);
};
ws.current.onclose = () => {
console.log('WebSocket is closed.');
};
ws.current.onerror = (error) => {
console.log('WebSocket error:', error);
};
};