Конструктор __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, код внутри не изменяется
- Создайте каталог 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";
}
}
- Используйте протокол 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();
- Тестирование
Откройте терминал, перейдите в каталог, где находится 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