1 <?php 2 //2、设计一个循环挂起WebSocket通道,进行数据的接收、处理和发送 3 //对创建的socket循环进行监听,处理数据 4 function run(){ 5 //死循环,直到socket断开 6 while(true){ 7 $changes=$this->sockets; 8 $write=NULL; 9 $except=NULL; 10 /* 11 //这个函数是同时接受多个连接的关键,我的理解它是为了阻塞程序继续往下执行。 12 socket_select ($sockets, $write = NULL, $except = NULL, NULL); 13 $sockets可以理解为一个数组,这个数组中存放的是文件描述符。当它有变化(就是有新消息到或者有客户端连接/断开)时,socket_select函数才会返回,继续往下执行。 14 $write是监听是否有客户端写数据,传入NULL是不关心是否有写变化。 15 $except是$sockets里面要被排除的元素,传入NULL是”监听”全部。 16 最后一个参数是超时时间 17 如果为0:则立即结束 18 如果为n>1: 则最多在n秒后结束,如遇某一个连接有新动态,则提前返回 19 如果为null:如遇某一个连接有新动态,则返回 20 */ 21 socket_select($changes,$write,$except,NULL); 22 foreach($changes as $sock){ 23 //如果有新的client连接进来,则 24 if($sock==$this->master){ 25 //接受一个socket连接 26 $client=socket_accept($this->master); 27 //给新连接进来的socket一个唯一的ID 28 $key=uniqid(); 29 $this->sockets[]=$client; //将新连接进来的socket存进连接池 30 $this->users[$key]=array( 31 'socket'=>$client, //记录新连接进来client的socket信息 32 'shou'=>false //标志该socket资源没有完成握手 33 ); 34 //否则1.为client断开socket连接,2.client发送信息 35 }else{ 36 $len=0; 37 $buffer=''; 38 //读取该socket的信息,注意:第二个参数是引用传参即接收数据,第三个参数是接收数据的长度 39 do{ 40 $l=socket_recv($sock,$buf,1000,0); 41 $len+=$l; 42 $buffer.=$buf; 43 }while($l==1000); 44 //根据socket在user池里面查找相应的$k,即健ID 45 $k=$this->search($sock); 46 //如果接收的信息长度小于7,则该client的socket为断开连接 47 if($len<7){ 48 //给该client的socket进行断开操作,并在$this->sockets和$this->users里面进行删除 49 $this->send2($k); 50 continue; 51 } 52 //判断该socket是否已经握手 53 if(!$this->users[$k]['shou']){ 54 //如果没有握手,则进行握手处理 55 $this->woshou($k,$buffer); 56 }else{ 57 //走到这里就是该client发送信息了,对接受到的信息进行uncode处理 58 $buffer = $this->uncode($buffer,$k); 59 if($buffer==false){ 60 continue; 61 } 62 //如果不为空,则进行消息推送操作 63 $this->send($k,$buffer); 64 } 65 } 66 } 67 } 68 } 69 ?>