EventListener::__construct

(PECL event >= 1.2.6-beta)

EventListener::__constructСоздаёт нового слушателя соединения, который связан с базой события

Описание

public EventListener::__construct(
     EventBase $base ,
     callable $cb ,
     mixed $data ,
     int $flags ,
     int $backlog ,
     mixed $target
)

Метод создаёт нового слушателя соединения, который связан с базой события.

Список параметров

base

База события.

cb

Значение с типом callable, которое вызывается при получении соединения.

data

Пользовательские данные, которые прикрепляются к callback-функции параметра cb.

flags

Битовая маска из семейства констант EventListener::OPT_*. Подробнее об этом рассказывает раздел «Константы класса EventListener».

backlog

Управляет максимальным количеством ожидающих подключений, которым сетевой стек должен разрешить в любое время ожидать в состоянии «ещё не принято». Дополнительную информацию смотрите в документации по функции listen текущей системы. При отрицательном значении параметра backlog модуль Libevent сам попытается выбрать наилучшее значение для параметра backlog. При нуле модуль Event предполагает, что функцию listen уже вызвали на сокете target.

target

Строка, ресурс сокета или поток, связанный с сокетом. При передаче в параметр target строкового аргумента, строка разбирается как сетевой адрес. Строка интерпретируется как путь сокета UNIX-домена, если содержит префикс 'unix:', например 'unix:/tmp/my.sock'.

Список изменений

Версия Описание
PECL-модуль event 1.5.0 Добавили поддержку сокетов UNIX-домена.

Примеры

Пример #1 Пример работы метода EventListener::__construct()

<?php

/*
* Простой сервер на основе слушателя соединений модуля libevent.
*
* Применение:
* 1) В одном окне терминала запустите команду:
*
* $ php listener.php 9881
*
* 2) В другом окне терминала откройте соединение, например:
*
* $ nc 127.0.0.1 9881
*
* 3) Начните печатать. Сервер должен повторить ввод.
*/

class MyListenerConnection
{
private
$bev, $base;

public function
__destruct()
{
$this->bev->free();
}

public function
__construct($base, $fd)
{
$this->base = $base;

$this->bev = new EventBufferEvent($base, $fd, EventBufferEvent::OPT_CLOSE_ON_FREE);

$this->bev->setCallbacks(array($this, "echoReadCallback"), NULL,
array(
$this, "echoEventCallback"), NULL);

if (!
$this->bev->enable(Event::READ)) {
echo
"Не удалось включить READ\n";
return;
}
}

public function
echoReadCallback($bev, $ctx)
{
// Скопируйте все данные из входного буфера в выходной буфер

// Вариант #1
$bev->output->addBuffer($bev->input);

/* Вариант #2 */
/*
$input = $bev->getInput();
$output = $bev->getOutput();
$output->addBuffer($input);
*/
}

public function
echoEventCallback($bev, $events, $ctx)
{
if (
$events & EventBufferEvent::ERROR) {
echo
"Ошибка bufferevent\n";
}

if (
$events & (EventBufferEvent::EOF | EventBufferEvent::ERROR)) {
//$bev->free();
$this->__destruct();
}
}
}

class
MyListener
{
public
$base,
$listener,
$socket;
private
$conn = array();

public function
__destruct()
{
foreach (
$this->conn as &$c) $c = NULL;
}

public function
__construct($port)
{
$this->base = new EventBase();
if (!
$this->base) {
echo
"Не удалось открыть событийную базу";
exit(
1);
}

// Вариант #1
/*
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_bind($this->socket, '0.0.0.0', $port)) {
echo "Невозможно связать сокет\n";
exit(1);
}
$this->listener = new EventListener($this->base,
array($this, "acceptConnCallback"), $this->base,
EventListener::OPT_CLOSE_ON_FREE | EventListener::OPT_REUSEABLE,
-1, $this->socket);
*/

// Вариант #2
$this->listener = new EventListener($this->base,
array(
$this, "acceptConnCallback"), $this->base,
EventListener::OPT_CLOSE_ON_FREE | EventListener::OPT_REUSEABLE, -1,
"0.0.0.0:$port");

if (!
$this->listener) {
echo
"Не удалось создать слушателя";
exit(
1);
}

$this->listener->setErrorCallback(array($this, "accept_error_cb"));
}

public function
dispatch()
{
$this->base->dispatch();
}

// Эта callback-функция вызывается, когда есть данные для чтения на $bev
public function acceptConnCallback($listener, $fd, $address, $ctx)
{
// Получили новое соединение! Создайте для этого, что требуется. */
$base = $this->base;
$this->conn[] = new MyListenerConnection($base, $fd);
}

public function
accept_error_cb($listener, $ctx)
{
$base = $this->base;

fprintf(STDERR, "Получил ошибку %d (%s) на слушателе."
."Выключение.\n",
EventUtil::getLastSocketErrno(),
EventUtil::getLastSocketError());

$base->exit(NULL);
}
}

$port = 9808;

if (
$argc > 1) {
$port = (int) $argv[1];
}

if (
$port <= 0 || $port > 65535) {
exit(
"Invalid port");
}

$l = new MyListener($port);
$l->dispatch();

?>
Добавить

Примечания пользователей 1 note

up
0
info-phpnet at ch2o dot info
10 years ago
Warning EventListener::OPT_CLOSE_ON_FREE is forced when you transmit a "target" string.

The only way to not set EventListener::OPT_CLOSE_ON_FREE is to bind the socket before creating EventListener and use this socekt as "target".
To Top