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. What identity values you get with the @@IDENTITY and SCOPE_IDENTITY functions

    --测试表及数据 CREATE TABLE TZ (   Z_id  int IDENTITY(1,1)PRIMARY KEY,   Z_name varchar(20) NOT NULL) INSE ...

  2. IT培训机构的招生诈骗大曝光

    作者曾在某知名IT培训机构工作过,目睹了招生欺诈,后来作者果断辞职,不能为奸商工作,助纣为虐,在此曝光,以免学生的血汗钱白交.社会上的IT培训机构手法大都一样,奸商都是有套路的.X大青鸟,X内外企IT ...

  3. css sprites拼合

    一.什么是css sprites css sprites直译过来就是CSS精灵.通常被解释为“CSS图像拼合”或“CSS贴图定位”.就是把网页中一些背景图片整合拼合成一张图片中,再利用DIV CSS的 ...

  4. ASP用户登录代码

    asp+access用户登录代码,其中huiyuan.mdb数据库名pUser213 表名y_username用户名字段,y_password密码字段. login.htm页面<head> ...

  5. Spring事务的传播行为分析

    前言 最近项目有涉及到Spring事务,所以工作之余,想认真了解学习下Spring事务,查阅了若干资料,做了一个demo(PS:参考了大牛的). 现分享总结如下: 1.Spring 事务的简介 理解事 ...

  6. codevs——T1267 老鼠的旅行

    http://codevs.cn/problem/1267/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descr ...

  7. Eclipse全局搜索

    按[Ctrl]+[H] 搜索时支持一些正则表达式. 参考: http://blog.csdn.net/huaweitman/article/details/38709323

  8. POJ3126——Prime Path

    非常水的一道广搜题(专业刷水题). .. #include<iostream> #include<cstdio> #include<queue> #include& ...

  9. MongoDB 索引的使用, 管理 和优化

    MongoDB 索引的使用, 管理 和优化 2014-03-25 17:12 6479人阅读 评论(0) 收藏 举报  分类: MongoDB(9)  [使用explain和hint] 前面讲高级查询 ...

  10. Android5.1开机LOGO与开机动画【转】

    本文转载自:http://blog.csdn.net/u014770862/article/details/52624627 android5.1中,开机LOGO部分和之前版本的并不相同,主要区别在于 ...