Конструктор __construct

Описание:

Worker::__construct([string $listen , array $context])

Инициализирует экземпляр контейнера Worker, позволяя задать некоторые свойства контейнера и интерфейсы обратных вызовов, чтобы выполнить определенные функции.

Параметры

$listen (необязательный параметр, если не указан, то не будет прослушиваться ни один порт)

Если указать параметр $listen, тогда будет выполнено прослушивание сокетов.

Формат $listen составляет <протокол>://<адрес прослушивания>

<протокол> может быть в следующих форматах:

tcp: например, tcp://0.0.0.0:8686

udp: например, udp://0.0.0.0:8686

unix: например, unix:///tmp/my_file (необходима версия Workerman>=3.2.7)

http: например, http://0.0.0.0:80

websocket: например, websocket://0.0.0.0:8686

text: например, text://0.0.0.0:8686 (text является встроенным текстовым протоколом Workerman, совместим с telnet, подробности см. в разделе Приложение о текстовом протоколе)

а также другие настраиваемые протоколы, см. в разделе данной документации о настраиваемых протоколах.

<адрес прослушивания> может быть в следующих форматах:

Если это unix-сокет, адресом будет локальный путь на диске.

Для не-unix-сокетов формат адреса будет <локальный ip>:<номер порта>

<локальный ip> может быть 0.0.0.0 для прослушивания всех сетевых интерфейсов локального хоста, включая внутренние и внешние ip-адреса, а также локальный loopback 127.0.0.1.

<локальный ip>, если равен 127.0.0.1, означает прослушивание только локального loopback, и доступ только с локального компьютера; внешний доступ невозможен.

<локальный ip>, если это внутренний ip, например, 192.168.xx.xx, будет означать прослушивание только внутреннего ip, и внешние пользователи не смогут получить доступ.

<локальный ip> не является адресом, который принадлежит локальному компьютеру, тогда прослушивание не может быть выполнено, и будет показана ошибка Cannot assign requested address.

Примечание: <номер порта> не может быть больше 65535. Если <номер порта> меньше 1024, то необходимо наличие прав root для его прослушивания. Порт, на который ведется прослушивание, должен быть свободен на локальном хосте, иначе прослушивание провалится с ошибкой Address already in use.

$context

Массив. Используется для передачи параметров контекста сокета, см. Параметры контекста сокета.

Примеры

Worker как http-контейнер для обработки http-запросов

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('http://0.0.0.0:8686');

$worker->onMessage = function(TcpConnection $connection, Request $request)
{
    $connection->send("hello");
};

// Запуск worker
Worker::runAll();

Worker как websocket-контейнер для обработки websocket-запросов

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('websocket://0.0.0.0:8686');

$worker->onMessage = function(TcpConnection $connection, $data)
{
    $connection->send("hello");
};

// Запуск worker
Worker::runAll();

Worker как tcp-контейнер для обработки tcp-запросов

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('tcp://0.0.0.0:8686');

$worker->onMessage = function(TcpConnection $connection, $data)
{
    $connection->send("hello");
};

// Запуск worker
Worker::runAll();

Worker как udp-контейнер для обработки udp-запросов

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('udp://0.0.0.0:8686');

$worker->onMessage = function(TcpConnection $connection, $data)
{
    $connection->send("hello");
};

// Запуск worker
Worker::runAll();

Worker для прослушивания unix domain сокета (требуется версия Workerman>=3.2.7)

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('unix:///tmp/my.sock');

$worker->onMessage = function(TcpConnection $connection, $data)
{
    $connection->send("hello");
};

// Запуск worker
Worker::runAll();

Worker без выполнения прослушивания, для обработки плановых задач

use \Workerman\Worker;
use \Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

$task = new Worker();
$task->onWorkerStart = function($task)
{
    // Выполнять каждые 2.5 секунды
    $time_interval = 2.5;
    Timer::add($time_interval, function()
    {
        echo "task run\n";
    });
};

// Запуск worker
Worker::runAll();

Worker для прослушивания порта пользовательского протокола

Итоговая структура каталогов

├── Protocols              // Это каталог Protocols, который нужно создать
│   └── MyTextProtocol.php // Это файл пользовательского протокола, который нужно создать
├── test.php  // Это тестовый скрипт, который нужно создать
└── Workerman // Каталог исходного кода Workerman, код внутри не изменяется
  1. Создайте каталог Protocols и файл протокола
    Protocols/MyTextProtocol.php (согласно приведенной выше структуре)
// Пространство имен пользовательского протокола строго должно быть Protocols
namespace Protocols;
// Простой текстовый протокол, формат протокола - текст + новая строка
class MyTextProtocol
{
    // Функция для разбиения пакетов, возвращает длину текущего пакета
    public static function input($recv_buffer)
    {
        // Поиск символа новой строки
        $pos = strpos($recv_buffer, "\n");
        // Если символ новой строки не найден, это значит, что пакет неполный, возвращаем 0 и продолжаем ждать данных
        if($pos === false)
        {
            return 0;
        }
        // Если символ новой строки найден, возвращаем длину текущего пакета, включая символ новой строки
        return $pos+1;
    }

    // После получения полного пакета происходит автоматическая декодировка через decode, здесь просто убираем символ новой строки
    public static function decode($recv_buffer)
    {
        return trim($recv_buffer);
    }

    // Перед отправкой данных клиенту они автоматически кодируются через encode, а затем отправляются клиенту, здесь добавляем новую строку
    public static function encode($data)
    {
        return $data."\n";
    }
}
  1. Используйте протокол MyTextProtocol для обработки запросов

Создайте файл test.php в соответствии с приведенной выше итоговой структурой

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

// #### Worker MyTextProtocol ####
$text_worker = new Worker("MyTextProtocol://0.0.0.0:5678");

/*
 * После получения полного пакета данных (с символом новой строки на конце) автоматически вызывается MyTextProtocol::decode('полученные данные')
 * Результат передается в обратный вызов onMessage через переменную $data
 */
$text_worker->onMessage =  function(TcpConnection $connection, $data)
{
    var_dump($data);
    /*
     * Чтобы отправить данные клиенту, автоматически вызывается MyTextProtocol::encode('hello world') для кодирования протокола,
     * а затем отправляются клиенту
     */
    $connection->send("hello world");
};

// Запуск всех worker
Worker::runAll();
  1. Тестирование

Откройте терминал, перейдите в каталог, где находится test.php, и выполните php test.php start

php test.php start
Workerman[test.php] старт в режиме DEBUG
----------------------- WORKERMAN -----------------------------
Версия Workerman:3.2.7          Версия PHP:5.4.37
------------------------ WORKERS -------------------------------
user          worker        listen                         processes status
root          none          myTextProtocol://0.0.0.0:5678   1         [OK]
----------------------------------------------------------------
Нажмите Ctrl-C для выхода. Успешно запущено.

Откройте терминал и используйте telnet для тестирования (рекомендуется использовать telnet из linux-системы)

Предположим, это тестирование на локальном компьютере,
в терминале выполните telnet 127.0.0.1 5678
затем введите hi и нажмите Enter
вы получите данные hello world\n

telnet 127.0.0.1 5678
Попытка 127.0.0.1...
Соединение с 127.0.0.1.
Символ для выхода — это '^>'.
hi
hello world