php实现socket推送技术的示例
在socket出现之前已经有ajax定时请求、长轮询等方案,但都不能满足需求,socket就应用而生了。
socket基本函数socket
总结下常用的socket函数
服务端:socket_create创建socket设置基本参数
socket_bind绑定ip和端口号
socket_listen监听
socket_accept客户端的连接
socket_read读取客户端的数据
socket_write给单独客户端发送数据
socket_close关闭连接
客户端:socket_create创建socket设置基本参数
socket_connect连接socket
socket_write给服务端发送数据
socket_read读取服务端数据
socket_close关闭连接
H5websocket不多说了,上链接
OK,开始贴代码~
----------------------------------------------------------分割线
服务端代码:
master=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)ordie("socket_create()failed"); socket_set_option($this->master,SOL_SOCKET,SO_REUSEADDR,1)ordie("socket_option()failed"); socket_bind($this->master,$address,$port)ordie("socket_bind()failed"); socket_listen($this->master,20)ordie("socket_listen()failed"); $this->sockets[]=$this->master; $this->say("ServerStarted:".date('Y-m-dH:i:s')); $this->say("Listeningon:".$address."port".$port); $this->say("Mastersocket:".$this->master."\n"); while(true){ $socketArr=$this->sockets; $write=NULL; $except=NULL; socket_select($socketArr,$write,$except,NULL);//自动选择来消息的socket如果是握手自动选择主机 foreach($socketArras$socket){ if($socket==$this->master){//主机 $client=socket_accept($this->master); if($client<0){ $this->log("socket_accept()failed"); continue; }else{ $this->connect($client); } }else{ $bytes=@socket_recv($socket,$buffer,2048,0); if($bytes==0){ $this->disConnect($socket); } else{ $key=array_search($socket,$this->sockets); if(empty($this->handshake)||!isset($this->handshake[$key])||!$this->handshake[$key]){ $this->doHandShake($socket,$buffer,$key); } else{ $buffer=$this->decode($buffer); echo$buffer.PHP_EOL; $key=array_search($socket,$this->sockets); $arr=$this->sockets; array_shift($arr); foreach($arras$s){ $this->send($s,$buffer); } } } } } } } functionsend($client,$msg){ $msg=$this->frame($msg); socket_write($client,$msg,strlen($msg)); } functionconnect($socket){ array_push($this->sockets,$socket); $this->say("\n".$socket."CONNECTED!"); $this->say(date("Y-n-dH:i:s")); } functiondisConnect($socket){ $index=array_search($socket,$this->sockets); socket_close($socket); $this->say($socket."DISCONNECTED!"); if($index>=0){ echo'unsetindexis:'.PHP_EOL; unset($this->sockets[$index]); } } functiondoHandShake($socket,$buffer,$handKey){ $this->log("\nRequestinghandshake..."); $this->log($buffer); list($resource,$host,$origin,$key)=$this->getHeaders($buffer); $this->log("Handshaking..."); $upgrade="HTTP/1.1101SwitchingProtocol\r\n". "Upgrade:websocket\r\n". "Connection:Upgrade\r\n". "Sec-WebSocket-Accept:".$this->calcKey($key)."\r\n\r\n";//必须以两个回车结尾 $this->log($upgrade); $sent=socket_write($socket,$upgrade,strlen($upgrade)); $this->handshake[$handKey]=true; $this->log("Donehandshaking..."); returntrue; } functiongetHeaders($req){ $r=$h=$o=$key=null; if(preg_match("/GET(.*)HTTP/",$req,$match)){$r=$match[1];} if(preg_match("/Host:(.*)\r\n/",$req,$match)){$h=$match[1];} if(preg_match("/Origin:(.*)\r\n/",$req,$match)){$o=$match[1];} if(preg_match("/Sec-WebSocket-Key:(.*)\r\n/",$req,$match)){$key=$match[1];} returnarray($r,$h,$o,$key); } functioncalcKey($key){ //基于websocketversion13 $accept=base64_encode(sha1($key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11',true)); return$accept; } functiondecode($buffer){ $len=$masks=$data=$decoded=null; $len=ord($buffer[1])&127; if($len===126){ $masks=substr($buffer,4,4); $data=substr($buffer,8); } elseif($len===127){ $masks=substr($buffer,10,4); $data=substr($buffer,14); } else{ $masks=substr($buffer,2,4); $data=substr($buffer,6); } for($index=0;$indexdebug){ echo$msg."\n"; } } } newWS('localhost',4000);
客户端代码(H5):
demo varws=newWebSocket("ws://localhost:4000"); ws.onopen=function(){ console.log("握手成功"); } ws.onmessage=function(e){ console.log("message:"+e.data); } ws.onerror=function(){ console.log("error"); } $("#send").click(function(){ content=$("#content").val(); console.log(content); ws.send(content); })
然后执行phpdemo.php开启socket(从运维那偷学一招,linux下执行nohupphpdemo.php&可以在后台执行),浏览器打开多个index.html,就能建立通讯了。
代码解析:
1.属性$sockets数组保存每个accept连接(不知道这么描述对不对);
2.属性$handshake数组保存连接是否在连接状态;
以上这篇php实现socket推送技术的示例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。