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, представляющий слушатель события соединения.

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

Версия Описание
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$fdEventBufferEvent::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 <= || $port 65535) {
    exit(
"Invalid port");
}

$l = new MyListener($port);
$l->dispatch();
?>
add a note add a note

User Contributed Notes 1 note

up
1
info-phpnet at ch2o dot info
5 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