@RigelGL

Как сделать глобальный массив с доступом из нескольких потоков в PHP?

Доброго времени суток.
Я в данный момент разрабатываю веб сервер на PHP 7.4.11, использующий сокеты и HTTP протокол для получения сообщений от Android-клиента.
Для обработки сокетов и запросов от Android-клиента использую библиотеку Workerman, сайт работает на Apache 2.4.

При получении сообщения от Android'а нужно отправить сообщения через websocket'ы клиентам на сайте.
Имеется файл global_vars.php со следующим содержанием:
<?php

namespace global_vars;

class Globals {
    private static $connections = array();

    public static function add($connection) { Globals::$connections[$connection->id] = $connection; }
    public static function remove($connection) { unset(Globals::$connections[$connection->id]); }
    public static function get($id) { return Globals::$connections[$id]; }

    public static function keys() { return array_keys(Globals::$connections); }
}


При подключении нового сокета я добавляю его в массив соединений:
include_once "global_vars.php";
global_vars\Globals::add($connection);


Я ожидаю, что при получении запроса от Android-клиента, который обработается в файле apiServer.php, я смогу получить текущие websocket'ы:
include_once "global_vars.php";
global_vars\Globals::get($target)->send("Message from android");


Однако массив global_vars\Globals::$connections из файла global_vars.php оказывается пуст.

Как решить проблему с массивом? Или для решения моей задачи нужно использовать иную архитектуру сервера?

Дополнительно проверял с инкрементацией счётчика в Globals, и он оказывался уникальным для обоих потоков (wsServer.php и apiServer.php), что весьма странно, так как он был статическим (static public $i = 0).
  • Вопрос задан
  • 183 просмотра
Пригласить эксперта
Ответы на вопрос 2
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
Попробуйте redis. Возможно он вам подойдёт
Ответ написан
@MaLuTkA_UA
Раз вы начали работать с workerman нужно было почитать документацию как и что там делать, и зайти на гит и почитать ответы разработчика на вопросы, там много полезного. Увы ваша реализация на сколько я понял не правильна, так как если запустить воркерман в несколько потоков у вас будут проблемы с поиском соединения, также для того чтобы отправить данные в сокет вам нужно в каждом процессе открыть TCP соединение через которое и будет происходить отправка сообщений, это тоже есть в их документации.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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