Bvivg
@Bvivg

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

<?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 позже и поэтому он вывел корректные значения
  • Вопрос задан
  • 71 просмотр
Пригласить эксперта
Ответы на вопрос 1
@MaLuTkA_UA
Коллбек функция onWorkerStart вызывается один раз при запуске каждого процесса воркера. Эта функция служит для конфигурации процесса то есть в ней вы например устанавливаете соединение с радис или прописываете таймер для пингов (он требуется для очистки соединений, потому что если пользователь отключился без предварительного уведомления у вас останется висеть коннект).
Когда пользователь подключается у вас срабатывает коллбек onConnect и вот в нем вы уже производите какие то действие с пользователем и что то ему там отправляете.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы