Пример использования веб-сокетов на php с workerman

231
21 августа 2018, 17:20

приведите, пожалуйста, пример использования библиотеки workerman. Весь интернет испещрен примерами типа helloworld, которых я уже по памяти десяток могу сам воспроизвести, но для решения практических задач они бесполезны. Очень не хватает теории по применению.

Никак не найти ни документации, ни статей (кроме примитивных), я уже читал японский или китайский оригинал с гуглтранслейтом, скачивал исходники (опять же с иероглифами в комментариях), предлагаемые автором. Но очень трудно понять концепцию, суть библиотеки. Возможно, стоит изучить сами сокеты более глубоко, такой ответ меня тоже устроит, но попрошу опять же с конкретикой, что именно и где почитать.

Задача довольно проста: клиент коннектится к серверу, сообщает, какие сведения ему нужны, и начинает ждать сообщений. Фронтовая часть ясна, а вот как на backend'е пробросить сообщение клиенту - никак не понять. Где и что инициировать, чтобы набор данных X, предназначенный клиенту Y, попал к нему.

Answer 1

Отправляем сообщение определенному пользователю

Сервер

<?php
    require_once __DIR__ . '/vendor/autoload.php';
    use Workerman\Worker;
// массив для связи соединения пользователя и необходимого нам параметра
$users = [];
// создаём ws-сервер, к которому будут подключаться все наши пользователи
$ws_worker = new Worker("websocket://0.0.0.0:8000");
// создаём обработчик, который будет выполняться при запуске ws-сервера
$ws_worker->onWorkerStart = function() use (&$users)
{
    // создаём локальный tcp-сервер, чтобы отправлять на него сообщения из кода нашего сайта
    $inner_tcp_worker = new Worker("tcp://127.0.0.1:1234");
    // создаём обработчик сообщений, который будет срабатывать,
    // когда на локальный tcp-сокет приходит сообщение
    $inner_tcp_worker->onMessage = function($connection, $data) use (&$users) {
        $data = json_decode($data);
        // отправляем сообщение пользователю по userId
        if (isset($users[$data->user])) {
            $webconnection = $users[$data->user];
            $webconnection->send($data->message);
        }
    };
    $inner_tcp_worker->listen();
};
$ws_worker->onConnect = function($connection) use (&$users)
{
    $connection->onWebSocketConnect = function($connection) use (&$users)
    {
        // при подключении нового пользователя сохраняем get-параметр, который же сами и передали со страницы сайта
        $users[$_GET['user']] = $connection;
        // вместо get-параметра можно также использовать параметр из cookie, например $_COOKIE['PHPSESSID']
    };
};
$ws_worker->onClose = function($connection) use(&$users)
{
    // удаляем параметр при отключении пользователя
    $user = array_search($connection, $users);
    unset($users[$user]);
};
// Run worker
Worker::runAll();

Клиент

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <script>
        ws = new WebSocket("ws://127.0.0.1:8000/?user=tester01");
        ws.onmessage = function(evt) {alert(evt.data);};
    </script>
</head>
</html>

Отправляем сообщение

<?php
$localsocket = 'tcp://127.0.0.1:1234';
$user = 'tester01';
$message = 'test';
// соединяемся с локальным tcp-сервером
$instance = stream_socket_client($localsocket);
// отправляем сообщение
fwrite($instance, json_encode(['user' => $user, 'message' => $message])  . "\n");
READ ALSO
GetCurPage в Битрикс

GetCurPage в Битрикс

Как в битриксе перечислить страницы в конструкции:

194
Как добавить изображение в товар UMI CMS?

Как добавить изображение в товар UMI CMS?

В кастомном обработчике ивента, произвожу запись из одного поля товара в другое, но изображение почему-то не записываетсяКод:

197
Как сгруппировать элементы массивов?

Как сгруппировать элементы массивов?

Подскажите, пожалуйста, идеи, как можно сгруппировать такого рода массивы:

198