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' .

Возвращаемые значения

Возвращает объект EventListener, представляющий слушатель события соединения.

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

Версия Описание
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();
?>