<?php
use Workerman\Worker;
use Workerman\Lib\Timer;
require './vendor/autoload.php';
$connect = require './system/db.php';
$ws_worker = new Worker("websocket://0.0.0.0:2346");
$ws_worker->onConnect = function ($connection) {
echo "соединение открыто\n";
};
$ws_worker->onClose = function ($connection) {
echo "соединение закрыто\n";
};
$ws_worker->onWorkerStart = function () use ($ws_worker) {
Timer::add(1, function () use ($ws_worker) {
global $userId, $receiverId, $connect;
$allMessages = getMessages($userId, $receiverId);
$newMessages = getNewMessages($userId, $receiverId);
foreach ($ws_worker->connections as $connection) {
$connection->send(json_encode(['all_messages' => $allMessages, 'new_messages' => $newMessages]));
markMessageAsRead($userId, $receiverId);
}
});
};
$ws_worker->onMessage = function ($connection, $data) {
global $userId, $receiverId, $message_text, $connect;
$decodedData = json_decode($data, true);
$userId = isset($decodedData['user_id']) ? $decodedData['user_id'] : null;
$receiverId = isset($decodedData['receiverId']) ? $decodedData['receiverId'] : null;
$message_text = isset($decodedData['message_text']) ? $decodedData['message_text'] : null;
echo '$userId: ' . $userId . PHP_EOL;
echo '$receiverId: ' . $receiverId . PHP_EOL;
if (!empty($message_text)) {
sendMessage($userId, $receiverId, $message_text);
}
};
function sendMessage($userId, $receiverId, $messageText)
{
global $connect;
$query = "INSERT INTO messages (sender_id, receiver_id, message_text, date, time, read_status, status)
VALUES (:userId, :receiverId, :messageText, NOW(), NOW(), 0, 0)";
$stmt = $connect->prepare($query);
$stmt->bindParam(':userId', $userId, PDO::PARAM_INT);
$stmt->bindParam(':receiverId', $receiverId, PDO::PARAM_INT);
$stmt->bindParam(':messageText', $messageText, PDO::PARAM_STR);
$stmt->execute();
}
function getMessages($userId, $receiverId)
{
global $connect;
$query = "SELECT * FROM messages
WHERE ((sender_id = :userId AND receiver_id = :receiverId)
OR (sender_id = :receiverId AND receiver_id = :userId))";
$stmt = $connect->prepare($query);
$stmt->bindParam(':userId', $userId, PDO::PARAM_INT);
$stmt->bindParam(':receiverId', $receiverId, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function getNewMessages($userId, $receiverId)
{
global $connect;
$query = "SELECT * FROM messages
WHERE read_status = 0 AND status = 1
AND ((sender_id = :userId AND receiver_id = :receiverId)
OR (sender_id = :receiverId AND receiver_id = :userId))
ORDER BY date, time";
$stmt = $connect->prepare($query);
$stmt->bindParam(':userId', $userId, PDO::PARAM_INT);
$stmt->bindParam(':receiverId', $receiverId, PDO::PARAM_INT);
$stmt->execute();
$updateQuery = "UPDATE messages SET read_status = 1, status = 1
WHERE receiver_id = :userId AND sender_id = :receiverId AND read_status = 0";
$updateStmt = $connect->prepare($updateQuery);
$updateStmt->bindParam(':userId', $userId, PDO::PARAM_INT);
$updateStmt->bindParam(':receiverId', $receiverId, PDO::PARAM_INT);
$updateStmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function markMessageAsRead($userId, $receiverId)
{
global $connect;
$updateQuery = "UPDATE messages SET read_status = 1, status = 1
WHERE receiver_id = :userId AND sender_id = :receiverId AND read_status = 0";
$updateStmt = $connect->prepare($updateQuery);
$updateStmt->bindParam(':userId', $userId, PDO::PARAM_INT);
$updateStmt->bindParam(':receiverId', $receiverId, PDO::PARAM_INT);
$updateStmt->execute();
}
Worker::runAll();
вот при вызове класса timer внутри onWorkerStart система не получает id получателя/отправителя. и при вызове ЕДИНОЖДЫ этой части кода
echo '$userId: ' . $userId . PHP_EOL;
echo '$receiverId: ' . $receiverId . PHP_EOL;
отладка в консоли вызывается дважды т.е.
$userId:
$receiverId:
$userId: 1
$receiverId: 9 т.е в первый раз система не получила id отправителя/получателя, а во второй раз получила и вывела корректные данные. Вышеописанную проблему насчет класса Timer внутри onWorkerStart это теория. Почему я слелал такой вывод? спросите вы. Т.к. я вызвал onWorkerStart первее нежели onMessage поэтому он выдал пустые значения, а onMessage позже и поэтому он вывел корректные значения