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. 10.IDEAD 的xml中配置DTD

    此时发现最后一行已经变成绿色就说明可以了,有提示了

  2. Python 实现 Excel 里单元格的读写与清空操作

    #coding=utf-8 # coding=utf-8 作用是声明python代码的文本格式是utf-8,python按照utf-8的方式来读取程序. # 如果不加这个声明,无论代码中还是注释中有中 ...

  3. 合并目录中的txt文件

    txt 文件 合并 并 按章节 分隔 # -*- coding: utf8 -*- import os result_name = 'result.txt' def resplit_txt_in_fo ...

  4. redhat超级用户密码破解

    1. 开机在出现grub画面,按e键 2. 用上下键选中第二项(类似于kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/) 然后按e键编辑 3. 空格sing ...

  5. @requestbody @responsebody详解

    @requestbody @responsebody详解 会唤起spring mvc的httpmessageconveter转换类进行数据转换 简介: @RequestBody 作用: i) 该注解用 ...

  6. kafka内置的zookeeper

    kafka 很多说不需要安装zk的是因为他们都使用了kafka自带的zk 至于kafka为什么使用zk,你首先要知道zk的作用, 作为去中心化的集群模式. 需要要消费者知道现在那些生产者(对于消费者而 ...

  7. 多个线程作用于同一个runnable对象

    多个线程作用于同一个runnable对象 学习了:https://www.cnblogs.com/ligang305/archive/2012/08/10/2632126.html http://as ...

  8. 初中级DBA必需要学会的9个Linux网络命令,看看你有哪些还没用过

    笔者不久前写了一篇文章<做DBA必须学会,不会会死的11个Linux基本命令>,博文地址为:http://blog.csdn.net/ljunjie82/article/details/4 ...

  9. Java高级程序猿技术积累

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveDczNDQwMDE0Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  10. java根据内容生成二维码图片

    package util; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; ...