警告 EventListener::OPT_CLOSE_ON_FREE 在您传输“目标”字符串时会被强制执行。
唯一不设置 EventListener::OPT_CLOSE_ON_FREE 的方法是在创建 EventListener 之前绑定套接字,并使用此套接字作为“目标”。
(PECL event >= 1.2.6-beta)
EventListener::__construct — 创建与事件基础关联的新连接监听器
$base
,$cb
,$data
,$flags
,$backlog
,$target
创建与事件基础关联的新连接监听器。
base
关联的事件基础。
cb
一个 callable ,当收到新连接时会调用该函数。
data
附加到 cb
的自定义用户数据。
flags
EventListener::OPT_*
常量的位掩码。参见 EventListener 常量 。
backlog
控制网络堆栈在任何时间点允许等待的待接受状态的挂起连接的最大数量;有关更多详细信息,请参见您系统 listen
函数的文档。如果 backlog
为负数,Libevent 会尝试为 backlog
选择一个好的值;如果为零,Event 假设已对套接字 (target
) 调用了 listen
。
target
可以是字符串、套接字资源或与套接字关联的流。如果 target
是字符串,则该字符串将被解析为网络地址。如果以 'unix:'
为前缀,例如 'unix:/tmp/my.sock'
,它将被解释为 UNIX 域套接字路径。
版本 | 描述 |
---|---|
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 "Failed to enable 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 "Error from 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 "Couldn't open event base";
exit(1);
}
// 选项 #1
/*
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_bind($this->socket, '0.0.0.0', $port)) {
echo "Unable to bind socket\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 "Couldn't create listener";
exit(1);
}
$this->listener->setErrorCallback(array($this, "accept_error_cb"));
}
public function dispatch() {
$this->base->dispatch();
}
// 当 $bev 上有数据可读时,此回调将被调用
public function acceptConnCallback($listener, $fd, $address, $ctx) {
// 我们获得了新的连接!为其设置一个 bufferevent。 */
$base = $this->base;
$this->conn[] = new MyListenerConnection($base, $fd);
}
public function accept_error_cb($listener, $ctx) {
$base = $this->base;
fprintf(STDERR, "Got an error %d (%s) on the listener. "
."Shutting down.\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();
?>
警告 EventListener::OPT_CLOSE_ON_FREE 在您传输“目标”字符串时会被强制执行。
唯一不设置 EventListener::OPT_CLOSE_ON_FREE 的方法是在创建 EventListener 之前绑定套接字,并使用此套接字作为“目标”。