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. Solr数据不同步

    Solr配置了集群,本地有253和254,2个独立的Solr服务.  同一个页面的图片,刷新2次,图片地址不一样,最后查明,后台数据源Solr1和Solr2的数据不一致.    第1步推测:本地缓存, ...

  2. C语言——定义&&声明

    1.变量的定义&声明 变量的声明有两种情况: <1>一种是需要建立存储空间的.例如:int a 在声明的时候就已经建立了存储空间. <2>另一种是不需要建立存储空间的. ...

  3. hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

    题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> ...

  4. C#之简易猜数字游戏

    游戏规则说明: 由系统生成一个随机数,玩家有三次猜数字的机会,如果在三次内猜出数字反馈玩家猜对了,否则Game Over! 代码设计说明: 1.首先设计一个简易的欢迎界面,并提示玩家是否开始游戏: p ...

  5. POJ1151 Atlantis 【扫描线】

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16882   Accepted: 6435 Descrip ...

  6. Value Stewardship Over Showmanship

     Value Stewardship Over Showmanship Barry Hawkins WHEn An ARCHiTECT EnTERS A pRojECT, there is an u ...

  7. c21---结构体

    // // main.c // 结构体基本概念 // #include <stdio.h> int main(int argc, const char * argv[]) { /* 基本数 ...

  8. php建立简单的用户留言系统

    php建立简单的用户留言系统 样例 addMsg.php--添加留言页面 doAction.php--响应添加留言页面 . viewMsg.php--显示留言页面 目录结构 addMsg.php--添 ...

  9. 高效管理 Elasticsearch 中基于时间的索引——本质是在利用滚动模式做数据的冷热分离,热索引可以用ssd

    高效管理 Elasticsearch 中基于时间的索引 转自:http://stormluke.me/es-managing-time-based-indices-efficiently/ 用 Ela ...

  10. 分布式系统CAP原则与BASE思想

    一.CAP原则 CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性). Availability(可用性).Partition tolerance(分区容错性),三者 ...