PHP+Socket系列之IO多路复用及实现web服务器

藏色散人
发布: 2023-04-11 10:20:01
转载
3902 人浏览过

本篇文章给大家带来了关于php+socket的相关知识,其中主要介绍了IO多路复用,以及php+socket如何实现web服务器?感兴趣的朋友下面一起来看一下,希望对大家有帮助。

php原生socket之IO多路复用以及实现web服务器

多路复用

前文通过原生 socket 实现了简单的服务端与客户端通信,但当有多个客户端连接时,服务端仅能处理第一个客户端的请求,而无法对后续客户端服务

服务端未正确处理截图

产生这种情况的原因是因为IO模型是阻塞的,同一时刻只能由一个客户端进行访问,解决此问题主要有两种解决方案:

  • 多进程,即在服务端启动多个进程监听

  • IO多路复用机制,简单来说实现了 N 个客户端使用一根网线同时访问

同时多路复用又分为两个不同的模型,即selectepoll,常见的软件中,Apache使用了select模型,nginx则使用epoll模型。在 php 中内置了select模型,对应的函数为socket_select,多路复用是实现 http 服务器的基础

语法

在前文中我们介绍了 php 原生 socket 内置了socket_select函数实现了select模型,其语法如下:

socket_select( array &$read, array &$write, array &$except, int $seconds [, int $microseconds = 0]): int|false
登录后复制

参数

  • read

    服务端监听的套接字资源,当他有变化(即收到新的消息或有客户端连接、断开)时,socket_select函数才会返回(否则继续阻塞),同时修改该变量为当前发生事件(收到消息或有客户端连接、断开)的套接字资源列表,并继续向下执行。

  • write

    监听是否有客户端写数据,传入null则代表不关心是否有写变化

  • except

    套接字内要排除的元素,传入null是 「监听」 全部

  • seconds

    秒和微秒一起构成超时参数。如果传入null则会阻塞,为 0 非阻塞,如果是 >0 则为最大阻塞时间

  • microseconds

优化

我们在上篇文章简单实现了 socket 服务端监听与客户端的连接,接下来我们在服务端监听代码的基础上通过多路复用优化代码:


        
登录后复制

在本示例中socket_select函数会阻塞当前进程,当$tmp_sockets数组内的 socket 资源有新的客户端连接或断开或收到新消息时,会将$tmp_sockets数组修改为当前活跃的 socket 资源,随后通过遍历该数组处理业务逻辑

优化结果截图

使用socket实现简易http服务器

http 协议是在 socket 的基础上规定了指定的数据格式,所以我们只需在socket_write时按照格式发送数据,浏览器就可正常响应请求

this is php worker'; $len = strlen($output); $response = "HTTP/1.1 200 OK\r\n"; $response .= "content-type: text/html\r\n"; $response .= "server: php socket\r\n"; $response .= "Content-Length: {$len}\r\n\r\n"; $response .= $output; socket_write($sock, $response); } } }
登录后复制

在服务端运行此示例,随后在浏览器访问ip:8888,可以看到如下:

525569ef28e66ce2d2e0956b96f9d18.jpg

同时服务端会输出如下内容:

GET / HTTP/1.1 Host: 124.222.**.**:8888 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: jenkins-timestamper-offset=-28800000; _ga=GA1.1.1403944751.1652010033; _ga_2GM6102E19=GS1.1.1652802985.7.1.1652803014.0
登录后复制

该内容即为用户端请求原始数据,可解析此数据并根据请求做出响应,比如使用file_get_content读取指定文件内容返回给浏览器

推荐学习:《PHP视频教程

以上是PHP+Socket系列之IO多路复用及实现web服务器的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
来源:learnku.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!