1.理解事件
11)生活事件 略
12)框架事件
13)linux事件
2event事件扩展及安装
21)两个文件的下载及上传,或直接远程下载到linux(或虚拟主机)
libevent-2.18-stable.tar.gz
event-2.3.0.taz
把这两个文件下载下来,并上传至linux服务器(虚拟主机)
或直接
wget -c https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz -P /usr/local/src
wget -c http://pecl.php.net/get/event-2.3.0.tgz -P /usr/local/src
22)libevent-2.18-stable.tar.gz 安装,一定要先安装这个
$ tar -zxvf libevent-2.1.8-stable.tar.gz
$ cd libevent-2.1.8-stable
$ ./configure --prefix=/usr/local/libevent-2.1.8
$ make
$ make install
以上表明安装配置成功
25)扩展介绍
函数对象 作用 参考地址
EventBase-object 用于监控所有的事件 https://php.golaravel.com/class.eventbase.html
Event-object 事件类 https://php.golaravel.com/class.eventbase.html
Event::__construct() 用于注册事件 https://php.golaravel.com/event.construct.html
Event::add() 添加事件 https://php.golaravel.com/event.add.html
EventBase::__construct 创建一个应用监督事件 https://php.golaravel.com/eventbase.construct.html
EventBase::loop() 启动 https://php.golaravel.com/eventbase.loop.html
Event-flags 作用 参考地址
Event::READ 此标志表示当所提供的文件描述符(通常是流资源或套接字)准备好可读取时活动的事件。 https://php.golaravel.com/event.flags.html
Event::WRITE 标志表示当提供的文件描述符(通常是流资源或套接字)准备好写入时活动的事件。 https://php.golaravel.com/event.flags.html
Event::SIGNAL 用于实现信号检测。参见下面的“构造信号事件” https://php.golaravel.com/event.flags.html
Event::TIMEOUT 这个Event::TIMEOUT在构造事件时忽略标志:可以在事件发生时设置超时。加或者不是。 https://php.golaravel.com/event.flags.html
设置为$什么当超时发生时,回调函数的参数
26)event的理解及运用
理解
运用
深入Event::__construct()
The event base to associate with.
要关联的事件基础。即设置事件的应用类,能过EventBase $base,设置到Linux事件中
fdstream resource, socket resource, or numeric file descriptor. For timer events pass -1 . For signal events pass the signal number, e.g. SIGHUP .
流资源、套接字资源或数字文件描述符。对于计时器事件通过-1 。对于信号事件,传递信号号,例如SIGHUP 。
Event flags. See Event flags .事件标志
cbThe event callback. See Event callbacks .事件回调
argCustom data. If specified, it will be passed to the callback when event triggers.
自定义数据。如果指定,则在事件触发时,它将传递给回调。
Event::add — Makes event pending 使事件挂起
添加事件到设置事件应用类中
Marks event pending. Non-pending event will never occur, and the event callback will never be called. In conjuction with Event::del() an event could be re-scheduled by user at any time.
标记挂起的事件。非挂起事件永远不会发生,并且永远不会调用事件回调。与Event::del() 一起,用户可随时重新安排事件。
If Event::add() is called on an already pending event, libevent will leave it pending and re-schedule it with the given timeout(if specified). If in this case timeout is not specified, Event::add() has no effect.
如果Event::add() 在已挂起的事件上调用,libevent 将将其保持挂起状态,并在给定超时时重新计划它(如果指定)。如果未指定超时,则Event::add() 不起作用。
Timeout in seconds. 可选参数, 如果事件构造时,标识参数为Event::TIMEOUT ,可设置时间。
Returns TRUE on success. Otherwise FALSE
261)小试牛刀
定时器 iostar\test\event\time.php
<?php
//设置事件的应用类
$eventBase = new EventBase();
//定义事件类 参数Event::PERSIST标志在事件上设置,则事件是永久性的。这意味着即使激活了调用,事件仍为挂起状态。
// 参数Event::del()方法,使其非挂起。
$event=new Event($eventBase,-1,Event::TIMEOUT | Event::PERSIST,function(){
//事件类的动作
echo microtime(true)."间隔2单位,我来了\n";
});
//添加事件到设置事件应用类中 参数可选,如果事件构造时,标识参数为Event::TIMEOUT ,可设置时间
$event->add(2);
//2 多个定时器
/*$event2=new Event($eventBase,-1,Event::TIMEOUT | Event::PERSIST,function(){
//事件类的动作
echo microtime(true)."间隔0.5单位,神来了\n";
});
//添加事件到设置事件应用类中 参数可选,如果事件构造时,标识参数为Event::TIMEOUT ,可设置时间
$event2->add(0.5);*/
//启动
$eventBase->loop();
运行如下:
262)小试牛刀
补充:事件构造的回调函数
If a callback is registered for an event, it will be called when the event becomes active. To associate a callback with event one can pass a callable to either Event::__construct() , or Event::set() , or one of the factory methods like Event::timer() .
如果为事件注册了回调,则当事件变为活动状态时将调用该回调。若要将回调与事件关联,可以将可调用的项传递到事件:__construct() 或事件::set() 或工厂方法之一,如 Event::timer() 。
An event callback should match the following prototype:
事件回调应与以下原型匹配:
fd
The file descriptor, stream resource or socket associated with the event. For signal event fd is equal to the signal number.
与事件关联的文件描述符、流资源或套接字。对于信号事件等于信号数。fd
what
Bit mask of all events triggered.
触发的所有事件的位掩码。
arg
User custom data.
用户自定义数据
Event::timer() expects the callback to match the following prototype:
Event::timer() 要求回调与以下原型匹配
arg
User custom data.
用户自定义数据。
Event::signal() expects the callback to match the following prototype:
Event::signal() 要求回调与以下原型匹配
signum
The number of the triggered signal(e.g. SIGTERM ).
触发信号的数量(例如SIGTERM )。
arg
User custom data.
用户自定义数据。
服务端iostarjhy\test\event\server.php
<?php
// 建立协议服务
$server = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
var_dump($server);
$eventBase = new EventBase();
//Event 构造的回调参数
$event=new Event($eventBase,$server,Event::READ | Event::WRITE| Event::PERSIST,function($socket){
var_dump($socket);
$conn = stream_socket_accept($socket);
var_dump(fread($conn,65535));
fwrite($conn, 'hello client from sever of event,time ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
});
$event->add();
$eventBase->loop();
客户端iostarjhy\test\event\client.php
<?php
// 连接服务端
$fp = stream_socket_client("tcp://192.168.204.168:8000");
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "hello server-event");
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);
}
运行
与之前对比,原来时间长了会出现关于一直挂起的警告,而现在不会出现了。
263)了解 swoole的event运行
swoole的事件管理 event https://wiki.swoole.com/#/event
swoole event 服务端 iostarjhy\test\event\swooleEvent.php
<?php
// 建立协议服务
$server = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
var_dump($server);
//swoole_event_add(); //助手函数,同下,类静态方法
Swoole\Event::add($server, function($socket){
var_dump($socket);
$conn = stream_socket_accept($socket);
var_dump(fread($conn,65535));
fwrite($conn, 'hello client from swoole event,time ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
});
swoole event 客户端 iostarjhy\test\event\ client2.php
<?php
// 连接服务端
$fp = stream_socket_client("tcp://192.168.204.168:8000");
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "hello swoole event");
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);
}
运行
264) php-event运用的注意事项
swoole event的嵌套,正常,但php-event会有bug
swoole event 服务端iostarjhy\test\event\swooleEvent3.php
<?php
// 建立协议服务
$server = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
var_dump($server);
//swoole_event_add(); //助手函数,同下,类静态方法
Swoole\Event::add($server, function($socket){
$conn = stream_socket_accept($socket);
//嵌套
Swoole\Event::add($conn, function($socket){
var_dump(fread($socket,65535));
fwrite($socket, 'hello client from swoole event3,time ' . date('n/j/Y g:i a') . "\n");
Swoole\Event::del($socket);
fclose($socket);
});
});
swoole event客户端 iostarjhy\test\event\client3.php
<?php
// 连接服务端
$fp = stream_socket_client("tcp://192.168.204.168:8000");
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "hello swoole event3");
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);
}
运行
php-event的嵌套 bug
php-event嵌套服务端 iostarjhy\test\event\phpevent.php
<?php
// 建立协议服务
$server = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
$eventBase = new EventBase();
$event=new Event($eventBase,$server,Event::READ | Event::WRITE| Event::PERSIST,function($socket) use (&$eventBase){
var_dump($socket);
$conn = stream_socket_accept($socket);
$event2=new Event($eventBase,$conn,Event::READ | Event::WRITE| Event::PERSIST,function($socket){
var_dump($socket);
var_dump(fread($socket,65535));
fwrite($socket, 'hello client from php event,time ' . date('n/j/Y g:i a') . "\n");
fclose($socket);
});
$event2->add();
});
$event->add();
$eventBase->loop();
php-event客户端 iostarjhy\test\event\phpEventClient.php
<?php
// 连接服务端
$fp = stream_socket_client("tcp://192.168.204.168:8000");
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "hello php event");
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);
}
运行
虽未报错,但嵌套内的无效果,没有执行,即Event支持事件嵌套,但是不支持面向过程的方式嵌套,只支持面向对象的方式嵌套,具体参考如下:
<?php
class e
{
protected $client;
protected $eventBase;
public function __construct($eventBase,$client,&$count)
{
$this->eventBase = $eventBase;
$this->client = $client;
}
public function hander()
{
$event=new Event($this->eventBase,$this->client,Event::READ | Event::WRITE| Event::PERSIST,function($socket){
//var_dump($socket);
//对于建立处理时间
var_dump(fread($socket,65535));
fwrite($socket, 'hello client from php event,time ' . date('n/j/Y g:i a') . "\n");
fclose($socket);
($this->count[(int) $socket][Event::READ | Event::WRITE| Event::PERSIST])->free();
});
$event->add();
$this->count[(int) $this->client][Event::READ | Event::WRITE| Event::PERSIST] = $event;
}
}
<?php
require_once "e.php";
// 建立协议服务
$server = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
var_dump($server);
$count=[];
$eventBase = new EventBase();
$event=new Event($eventBase,$server,Event::READ | Event::WRITE| Event::PERSIST,function($socket) use (&$eventBase,&$count){
var_dump($socket);
$conn = stream_socket_accept($socket);
(new e($eventBase,$conn,$count))->hander();
});
$count[(int) $server][Event::READ | Event::WRITE| Event::PERSIST] = $server;
$event->add();
$eventBase->loop();
php-event客户端 iostarjhy\test\event\phpEventClient.php 同上,略
运行
注意:最终推荐用swoole event
未完待续:swoole 第8次课 更上层楼:异步io模型与单进程Reactor 2
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!