php libevent扩展具有很强大的功能。以下摘自百度百科:

  Libevent 是一个用C语言编写的、轻量级的开源高性能网络库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大;

源代码相当精炼、易读;跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,

定时器和信号等事件;注册事件优先级。

  在php 的libevent扩展具有如下函数:

  event_base_free()     释放资源,这不能销毁绑定事件
  event_base_loop()     处理事件,根据指定的base来处理事件循环
  event_base_loopbreak()     立即取消事件循环,行为和break语句相同
  event_base_loopexit()     在指定的时间后退出循环
  event_base_new()     创建并且初始事件
  event_base_priority_init()     设定事件的优先级
  event_base_set()     关联事件到事件base
  event_buffer_base_set()     关联缓存的事件到event_base
  event_buffer_disable()     禁用一个缓存的事件
  event_buffer_enable()     启用一个指定的缓存的事件
  event_buffer_fd_set()     改变一个缓存的文件系统描述
  event_buffer_free()     释放缓存事件
  event_buffer_new()     建立一个新的缓存事件
  event_buffer_priority_set()     缓存事件的优先级设定
  event_buffer_read()     读取缓存事件中的数据
  event_buffer_set_callback()     给缓存的事件设置或重置回调hansh函数
  event_buffer_timeout_set()     给一个缓存的事件设定超时的读写时间
  event_buffer_watermark_set     设置读写事件的水印标记
  event_buffer_write()     向缓存事件中写入数据
  event_add()     向指定的设置中添加一个执行事件
  event_del()     从设置的事件中移除事件
  event_free()     清空事件句柄
  event_new()     创建一个新的事件
  event_set()     准备想要在event_add中添加事件

event_set一些参数的解释:

  (a) EV_TIMEOUT: 超时
    (b) EV_READ: 只要网络缓冲中还有数据,回调函数就会被触发
    (c) EV_WRITE: 只要塞给网络缓冲的数据被写完,回调函数就会被触发
    (d) EV_SIGNAL: POSIX信号量
    (e) EV_PERSIST: 不指定这个属性的话,回调函数被触发后事件会被删除
    (f) EV_ET: Edge-Trigger边缘触发

下面看一下一个简单的用例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$socket = stream_socket_server("tcp://0.0.0.0:8000"$errno$errstr);
 
$base = event_base_new();
$event = event_new();
 
function read_cb($socket$flag$base) {
  fread($socket);
   fwrite("hello world\n");
}
 
function accept_cb($socket$flag$base) {
    $conn = stream_socket_accept($socket, 0);
    stream_set_blocking($conn, 0);
    $event = event_new();
    event_set($event$conn, EV_READ | EV_PERSIST, 'read_cb'$base);
    event_base_set($event$base);
    event_add($event);
}
 
event_set($event$socket, EV_READ | EV_PERSIST, 'accept_cb'$base);
event_base_set($event$base);
event_add($event);
event_base_loop($base);

  这一段是摘抄自 韩天峰 的一个PPT上的简单用例,我来给大家解释一下:

  首先创建一个 tcp服务,绑定 8000端口。创建一个 event_base,然后创建一个 event,通过 event_set设置 让event监听新创建的socket,并给这个event事件设置属性,可以看到其中指定了回调函数 accept_cb

然后将这个event与base进行绑定,并加入到监听事件中取,启动事件循环。

  可以发现 accept_cb做了接受客户端链接,并且又创建了一个event事件,做了跟之前一样的事情,并且指定了该事件的回调函数是read_cb。 而read_cb函数 做了读取和写入操作。

  下面我自己通过整理写一个客户端 client.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
/**
 * author: NickBai
 * createTime: 2016/12/17 0017 下午 3:00
 */
$socket_client = stream_socket_client('tcp://127.0.0.1:2000'$errno$errstr, 30);
fwrite($socket_client"hello world!");
sleep(1);
$return fread($socket_client, 1024);
echo "come from server : " $return . PHP_EOL;
sleep(2);
 
fwrite($socket_client"send again!");
$return fread($socket_client, 1024);
echo "come from server : " $return . PHP_EOL;

  我重新整理了一个具有实际可操作的 server 服务端代码如下

  server.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/17
 * Time: 20:59
 */
$socket = stream_socket_server("tcp://0.0.0.0:2000"$errno$errstr);
 
$base = event_base_new();
$event = event_new();
 
event_set($event$socket, EV_READ | EV_PERSIST, 'accept_cb'$base);
event_base_set($event$base);
event_add($event);
event_base_loop($base);
 
function read_cb($buffer)
{
    static $ct = 0; 
    $ct_last $ct
    $ct_data ''
    while ($read = event_buffer_read($buffer, 1024)) { 
        $ct += strlen($read); 
        $ct_data .= $read
    }
 
    $ct_size = ($ct $ct_last) * 8; 
    echo "client say : " $ct_data .PHP_EOL; 
    event_buffer_write($buffer"Received $ct_size byte data");
}
 
function write_cb($buffer)
{
    echo "我在打酱油 " . PHP_EOL;
}
 
function error_cb($buffer$error)
{
    // 客户端断开连接之后,清除
    event_buffer_disable($GLOBALS['buffer'], EV_READ | EV_WRITE); 
    event_buffer_free($GLOBALS['buffer']); 
    fclose($GLOBALS['connection']); 
    unset($GLOBALS['buffer'], $GLOBALS['connection']); 
}
 
function accept_cb($socket$flag$base)
{
    $connection = stream_socket_accept($socket);
    stream_set_blocking($connection, 0);
 
    $buffer = event_buffer_new($connection'read_cb''write_cb''error_cb'); 
    event_buffer_base_set($buffer$base); 
    event_buffer_timeout_set($buffer, 30, 30); 
    event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff); 
    event_buffer_priority_set($buffer, 10); 
    event_buffer_enable($buffer, EV_READ | EV_PERSIST); 
 
    // 必须将 $connection 和 $buffer 赋值给一个全局变量,否则无法生效
    $GLOBALS['connection'] = $connection;
    $GLOBALS['buffer'] = $buffer
}

php libevent扩展的简单用例的更多相关文章

  1. PHP libevent扩展安装

    libevent是一个基于事件驱动的高性能网络库.支持多种 I/O 多路复用技术, epoll. poll. dev/poll. select 和 kqueue 等:支持 I/O,定时器和信号等事件: ...

  2. 【转】网页游戏能用PHP做后端开发吗? PHP Libevent扩展安装及应用

    网页游戏能用PHP做后端开发吗? 当然可以.最好走HTTP,也可以做网络编程,而且写代码超简单,1个函数就可以建一个服务器端.stream_socket_server()多线程不是什么好主意,你可以用 ...

  3. extern外部方法使用C#简单样例

    外部方法使用C#简单样例 1.添加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", ...

  4. 利用PHP SOAP扩展实现简单Web Services

    原文:利用PHP SOAP扩展实现简单Web Services WebServices能干什么? WebServices 可以将应用程序转换为网络应用程序. 通过使用 WebServices,您的应用 ...

  5. spring事务详解(二)简单样例

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

  6. Docker Compose 创建yml 简单试例

    Docker Compose 创建yml 简单试例 Docker Compose 文件使用格式版本需要与Docker版本对应可在官网内查找 查找地址:https://docs.docker.com/c ...

  7. PHP Libevent扩展安装及应用

    http://www.phpddt.com/php/libevent.html PHP Libevent扩展安装及应用

  8. webpack -- 多页面简单小例

    有时单页面并不能满足我们的业务需求,就需要去构建多页面应用,以下为简单小例: entry:{ index:'./src/module/index/index.js', student:'./src/m ...

  9. velocity简单样例

    velocity简单样例整体实现须要三个步骤,详细例如以下: 1.创建一个Javaproject 2.导入须要的jar包 3.创建须要的文件 ============================= ...

随机推荐

  1. Git 基础教程 之 远程库更新到本地

    PS:git remote -v 查看远程仓库        git diff temp 比较master 分支与temp的不同 如果分支没有合并到主分支上,用        git branch - ...

  2. Java 实现线程安全的三种方式

    一个程序在运行起来的时候会转换成进程,通常含有多个线程. 通常情况下,一个进程中的比较耗时的操作(如长循环.文件上传下载.网络资源获取等),往往会采用多线程来解决. 比如显示生活中,银行取钱问题.火车 ...

  3. 转载 - AC自动机算法

    出处:http://blog.csdn.net/niushuai666/article/details/7002823 AC自动机简介:  首先简要介绍一下AC自动机:Aho-Corasick aut ...

  4. @Transactional 注解的使用和注意

    转载:http://epine.itpub.net/post/8159/526281 1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口 ...

  5. 0223实战:MySQL Sending data导致查询很慢的问题详细分析

    转自博客http://blog.csdn.net/yunhua_lee/article/details/8573621 [问题现象] 使用sphinx支持倒排索引,但sphinx从mysql查询源数据 ...

  6. mongodb--group聚合运算

    mongodb本质就是要做一个高性能,能简单则简单,不要把mongodb中的运算做的太复杂 count 最简单的一个聚合方法 distinct 选择结果中剔除重复的一个键值, 跟sql语句的效果是一样 ...

  7. Apache Shiro教程

    跟开涛学系列: 来自开涛的Apache Shiro教程:http://jinnianshilongnian.iteye.com/blog/2018398 附带的代码例子:https://github. ...

  8. Elo rating system(Elo 打分体系)

    A.B 两个待比较.评价的对象,分别打分为 RA,RB,则各自获胜的期望值为: ⎧⎩⎨⎪⎪⎪⎪⎪⎪EA=11+10(RB−RA)/400.EB=11+10(RA−RB)/400. 不妨令 QA=10R ...

  9. 【撸码caffe 二】 blob.hpp

    Blob类是caffe中对处理和传递的实际数据的封装,是caffe中基本的数据存储单元,包括前向传播中的图像数据,反向传播中的梯度数据以及网络层间的中间数据变量(包括权值,偏置等),训练模型的参数等等 ...

  10. VM-安装MAC系统

    搜了下论坛没有这个教程,继续搬运一波,这次教的是用VM15安装Mac OS10.14懒人版VMware安装Windows和Linux比较类似,相对于今天要安装的MAC OS来说过程也比较简单.官方原版 ...