CakeFest 2024: The Official CakePHP Conference

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

Callback-функция (callable), которая будет вызвана при получении соединения.

data

Пользовательские данные, которые будут передаваться в параметр 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();

?>
add a note

User Contributed Notes 1 note

up
0
info-phpnet at ch2o dot info
9 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