对socket的代码学习和自我理解与记录
<?phpclass Worker{
//监听socket
protected $socket = NULL;
//连接事件回调
public $onConnect = NULL;
//接收消息事件回调
public $onMessage = NULL;
public $workerNum=4; //子进程个数
public $allSocket; //存放所有socket
public function __construct($socket_address) {
//监听地址+端口
$this->socket=stream_socket_server($socket_address);
stream_set_blocking($this->socket,0); //设置非阻塞,这个主要影响资源流读取是不是阻塞1阻塞0非阻塞 非阻塞的时候会立即返回,不管有没有读取到,主要影响到的函数fgets() 和 fread()
$this->allSocket[(int)$this->socket]=$this->socket;//存放所有socket资源
}
public function start() {
$this->fork();
}
public function fork(){
$this->accept();
}
public function accept(){
while (true){
$write=$except=[];
//需要监听socket
$read=$this->allSocket;
//状态谁改变
stream_select($read,$write,$except,60);//这里是阻塞的,第五个参数没传默认是null(stream_select阻塞等待时间超过($tv_sec+$tv_usec)的时间总值,如果$tv_sec=&null时,则无限阻塞直到上面4种返回条件中的任何一种发生了)
//有状态变化后,比如可读状态
//怎么区分服务端跟客户端
foreach ($read as $index=>$val){
//当前发生改变的是服务端,有连接进入
if($val === $this->socket){
$clientSocket=stream_socket_accept($this->socket); //阻塞监听,服务器可读状态变化,照理来说这里应该是不会被阻塞的或者说应该很快读到数据
//触发事件的连接的回调
if(!empty($clientSocket) && is_callable($this->onConnect)){
call_user_func($this->onConnect,$clientSocket);//和$this->onConnect($clientSocket);好像等价
}
$this->allSocket[(int)$clientSocket]=$clientSocket;
}else{
//从连接当中读取客户端的内容
$buffer=fread($val,1024);//原本阻塞,上面设置过,不阻塞了
//如果数据为空,或者为false,不是资源类型
if(empty($buffer)){
if(feof($val) || !is_resource($val)){//feof是否已经到文件末尾
//触发关闭事件
fclose($val);
unset($this->allSocket[(int)$val]);
continue;
}
}
//正常读取到数据,触发消息接收事件,响应内容
if(!empty($buffer) && is_callable($this->onMessage)){
call_user_func($this->onMessage,$val,$buffer);
}
}
}
}
}
}
$worker = new Worker("tcp://0.0.0.0:9805");
//连接事件
$worker->onConnect = function ($fd) {
//echo "连接事件触发",(int)$fd,PHP_EOL;
};
//消息接收
$worker->onMessage = function ($conn, $message) {
//事件回调当中写业务逻辑
//var_dump($conn,$message);
$content="学习过程";
$http_resonse = "HTTP/1.1 200 OK
";
$http_resonse .= "Content-Type: text/html;charset=UTF-8
";
$http_resonse .= "Connection: keep-alive
"; //连接保持
$http_resonse .= "Server: php socket server
";
$http_resonse .= "Content-length: ".strlen($content)."
";
$http_resonse .= $content;
fwrite($conn, $http_resonse);//数据写入资源句柄
};
$worker->start(); //启动
以上是 对socket的代码学习和自我理解与记录 的全部内容, 来源链接: utcz.com/z/511844.html