概述为了更好的理解,网络编程,写出一个高性能的服务,我们需要花一些时间去了解服务端处理客户端的整个过程和为了理解一些关键术语,我本来想在本文中补充一些基础理论知识。担心文章篇幅不利于阅读,所以以后补发一些基础知识,再进入正题。理论主要介绍实现一个web服务器的基本步骤,代码会在实践中复现一次。第一步,我们需要创建一个socket,绑定服务器端口(bind),监听端口(listen),利用PHP中的stream_socket_server函数来完成以上三步。第二步进入while循环,阻塞在accept操作上,等待客户端连接进入。此时,程序会进入休眠状态,直到有新的客户端向服务器发起连接,操作系统才会唤醒该进程。accept函数返回客户端连接的套接字。第三步,使用fread读取clientsocket中的数据。服务器程序收到数据后,进行处理,然后使用fwrite向客户端发送响应。长连接服务会继续与客户端交互,而短连接服务一般会在收到响应后关闭。实践这里我们用代码来实现接下来的基本流程。在开始写代码之前,先介绍一下我们代码中可能用到的几个php函数,方便大家理解。Functionstream_socket_serverstream_socket_acceptcall_user_funcis_callablefread点击函数了解使用代码,废话少说直接开始~onConnect=function($data){echo'Anewconnectioniscoming',$data,PHP_EOL;};//预先注册了一个接收消息事件回调$worker->onMessage=function($conn,$message){};$工人->运行();按照前面的流程,我们需要监听端口+地址publicfunction__construct($socket_address){//监听地址+端口$this->socket=stream_socket_server($socket_address);}Next需要阻塞accept操作,等待客户端连接进入。此时程序会进入休眠状态,直到有新的客户端向服务器发起连接,操作系统才会唤醒进程publicfunctionrun(){while(true){//循环监听$client=stream_socket_accept($this->socket);//服务器端监听阻塞}}当有新连接进入唤醒过程,触发连接事件回调publicfunctionrun(){while(true){//循环监听$client=stream_socket_accept($this->socket);//阻塞监听服务器if(!empty($client)&&is_callable($this->onConnect)){//socket连接成功,是我们的回调//连接触发事件的回调call_user_func($这个->onConnect,$client);}}}这里的连接回调实际上会触发下面的代码$worker->onConnect=function($worker->onConnect=function($data){echo'connectionevent:',$data,PHP_EOL;};成功,使用fread获取客户端内容,触发接收消息事件publicfunctionrun(){while(true){//循环监听$client=stream_socket_accept($this->socket);//阻塞监听服务器if(!empty($client)&&is_callable($this->onConnect)){//socket连接成功,是我们的回调//连接触发事件的回调call_user_func($this->onConnect,$客户端);}//从连接中读取客户端内容$buffer=fread($client,65535);//参数2:buffer中读取的最大字节数//正常读取数据触发消息接收事件并响应if(!empty($buffer)&&is_callable($this->onMessage)){//触发时间消息接收事件call_user_func($this->onMessage,$this,$client,$buffer);//传递给接收到的消息事件“当前对象,当前连接,接收到的消息}}}至此,一个网络服务的基本接收就基本完成了,需要对请求进行响应。以HTTP请求为一个例子,封装了一个http响应方法(http://127.0.0.1:9810)classWorker{.........publicfunctionsend($conn,$content){$http_resonse="HTTP/1.1200OK\r\n";$http_resonse.="Content-Type:text/html;charset=UTF-8\r\n";$http_resonse.="Connection:keep-alive\r\n";$http_resonse.="Server:phpsocketserver\r\n";$http_resonse.="Content-length:".strlen($content)."\r\n\r\n";$http_resonse.=$content;fwrite($conn,$http_resonse);}}接收消息事件触发时响应http请求$worker->onMessage=function($server,$conn,$message){echo'来自客户端的消息:',$message,PHP_EOL;$server->send($conn,'来自服务器的消息');};到此结束~,完整代码直通车缺点只能处理一次Connections,不支持同时连接多个
