Почему при onWorkerStart при вызове функции timer система не может получить user_id и receiver_id из json?

Ссылка скопирована
PHP
1 ответ
<?php  use WorkermanWorker; use WorkermanLibTimer;  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();

<?php use WorkermanWorker; use WorkermanLibTimer; 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;

echo '$userId: ' . $userId . PHP_EOL; echo '$receiverId: ' . $receiverId . PHP_EOL;

отладка в консоли вызывается дважды т.е.
$userId:
$receiverId:
$userId: 1
$receiverId: 9 т.е в первый раз система не получила id отправителя/получателя, а во второй раз получила и вывела корректные данные. Вышеописанную проблему насчет класса Timer внутри onWorkerStart это теория. Почему я слелал такой вывод? спросите вы. Т.к. я вызвал onWorkerStart первее нежели onMessage поэтому он выдал пустые значения, а onMessage позже и поэтому он вывел корректные значения

Дополнительно:

Ответы:

Коллбек функция onWorkerStart вызывается один раз при запуске каждого процесса воркера. Эта функция служит для конфигурации процесса то есть в ней вы например устанавливаете соединение с радис или прописываете таймер для пингов (он требуется для очистки соединений, потому что если пользователь отключился без предварительного уведомления у вас останется висеть коннект).
Когда пользователь подключается у вас срабатывает коллбек onConnect и вот в нем вы уже производите какие то действие с пользователем и что то ему там отправляете.

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Андрей PHP Ответ

При вызове функции timer внутри метода onWorkerStart система не может получить user_id и receiver_id из json, потому что в момент запуска воркера данные user_id и receiver_id могут быть еще не инициализированы или не доступны.

Чтобы решить эту проблему, необходимо убедиться, что данные user_id и receiver_id доступны в момент вызова функции timer. Для этого можно использовать другие события или методы, которые гарантируют наличие этих данных. Например, можно вызвать функцию timer внутри другого метода, где данные уже будут доступны, или передавать необходимые данные в функцию timer как параметры.

Пример:

class MyWorker extends Worker
{
    public function onWorkerStart()
    {
        $user_id = $this->getUserID();
        $receiver_id = $this->getReceiverID();
 
        $this->startTimer($user_id, $receiver_id);
    }
 
    public function startTimer($user_id, $receiver_id)
    {
        // Ваш код здесь
    }
}

class MyWorker extends Worker { public function onWorkerStart() { $user_id = $this->getUserID(); $receiver_id = $this->getReceiverID(); $this->startTimer($user_id, $receiver_id); } public function startTimer($user_id, $receiver_id) { // Ваш код здесь } }

Таким образом, следует убедиться, что данные user_id и receiver_id доступны в момент вызова функции timer, чтобы избежать ошибок при обращении к ним из json.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно