14. PHP socket初探 – 含着泪也要磕完 libevent(三) - PHP 进阶教程

返回介绍

14. PHP socket初探 – 含着泪也要磕完 libevent(三)

发布于 2019-06-30 字数 2759 浏览 815 评论 0

这段时间相比大家也看到了,本人离职了,一是在家偷懒实在懒得动手,二是好不容易想写点儿时间全部砸到数据结构和算法那里了。

今儿回过头来,继续这里的文章。那句话是怎么说的:

自己选择的课题,含着泪也得磕完!”(图文无关,详情点击这里)。

14. PHP socket初探 - 含着泪也要磕完 libevent(三)

其实在上一篇 libevent 文章中(<a href="” title=”《PHP socket初探 — 硬着头皮继续libevent(二)》”>《PHP socket初探 — 硬着头皮继续libevent(二)》),如果你总结能力很好的话,可以观察出来我们尝试利用libevent做了至少两件事情:

  • 毫秒级别定时器
  • 信号监听工具

大家都是码php的,也喜欢把自己说的洋气点儿:“ 我是写服务器的 ”。所以,今天的第一个案例就是拿libevent来构建一个简单粗暴的http服务器:

<?php
$host = '0.0.0.0';
$port = 9999;
$listen_socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
socket_bind( $listen_socket, $host, $port );
socket_listen( $listen_socket );

echo PHP_EOL.PHP_EOL."Http Server ON : http://{$host}:{$port}".PHP_EOL;

// 将服务器设置为非阻塞,此处概念可能略拐弯,建议各位查阅一下手册
socket_set_nonblock( $listen_socket );
// 创建事件基础体,还记得航空母舰吗?
$event_base = new EventBase();
// 创建一个事件,还记得歼15舰载机吗?我们将“监听socket”添加到事件监听中,触发条件是read,也就是说,一旦“监听socket”上有客户端来连接,就会触发这里,我们在回调函数里来处理接受到新请求后的反应
$event = new Event( $event_base, $listen_socket, Event::READ | Event::PERSIST, function( $listen_socket ){
  // 为什么写成这样比较执拗的方式?因为,“监听socket”已经被设置成了非阻塞,这种情况下,accept是立即返回的,所以,必须通过判定accept的结果是否为true来执行后面的代码。一些实现里,包括workerman在内,可能是使用@符号来压制错误,个人不太建议这>样做
  if( ( $connect_socket = socket_accept( $listen_socket ) ) != false){
    echo "有新的客户端:".intval( $connect_socket ).PHP_EOL;
    $msg = "HTTP/1.0 200 OK\r\nContent-Length: 2\r\n\r\nHi";
    socket_write( $connect_socket, $msg, strlen( $msg ) );
    socket_close( $connect_socket );
  }
}, $listen_socket );
$event->add();
$event_base->loop();

将代码保存为test.php,然后php http.php运行起来。再开一个终端,使用curl的GET方式去请求服务器,效果如下:

14. PHP socket初探 - 含着泪也要磕完 libevent(三)

这是一个非常非常简单地不能再简单的http demo了,对于一个完整的http服务器而言,他还差比较完整的http协议的实现、多核CPU的利用等等。这些,我们会放到后面继续深入的文章中开始细化丰富。

还记得我们使用select系统调用实现了一个粗暴的在线聊天室,select这种业余的都敢出来混个聊天室,专业的绝对不能怂。

无数个专业

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!