通过http推送消息给socket,socket服务再向客户端推送
<?php /* * Socket推送 * 请用守护进程方式启动php msgservice.php & (socket只支持linux) * 默认使用SWOOLE_PROCESS模式,echo终端是禁止的,如果要观察日志,保存到log中. * status=1,小程序推送 * status=2,点餐机->socket->身份识别 * status=3,socket->点餐机->推送订单 * status=4,点餐机->socket->告知消息已经处理 */ class WebsocketServer { public $server; //主机群 private $client=array(); //消息群 private $clientmsg=array(); public function __construct() { //01.绑定网卡 $this->server = new swoole_websocket_server("0.0.0.0", 9502); //02.主动握手 $this->server->on('open', function (swoole_websocket_server $server, $request) { //echo "server: handshake success with fd{$request->fd}\n"; }); //03.消息获取 $this->server->on('message', function (swoole_websocket_server $server, $frame) { //echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n"; //3.1.记录客户端信息 $data=json_decode($frame->data,true); if(isset($data['status']) && $data['status']==2){ $rev=array( 'hostfd'=>$frame->fd,//'在swoole中是顺序' 'shopid'=>$data['shopid'], ); //新来的客户端,看看是否有你的订单 foreach ($this->clientmsg as $value) { if($value['shopid']==$rev['shopid']){ //echo 'have'; $data=json_encode($value); $server->push($frame->fd,$data); break; } } //多个终端只识别第一个 $isnew=1; foreach ($this->client as $value) { if($value['shopid']==$rev['shopid']){ $isnew=0; break; } } if($isnew){ array_push($this->client,$rev); } else { //echo 'This client duplication,now client num:'.count($this->client).'\n'; } } //3.2.点餐机已经处理的消息直接清理 if( isset($data['status']) && $data['status']==3){ $orderid=$data['orderid']; foreach ($this->clientmsg as $key => $value) { if($value['orderid']==$orderid){ unset($this->clientmsg[$key]); array_merge($this->clientmsg); //echo 'order is reved!'; break; } } } }); //04.断开事件,清理无效主机 $this->server->on('close', function ($ser, $fd) { foreach ($this->client as $key => $value) { if($value['hostfd']==$fd){ unset($this->client[$key]); array_merge($this->client); } } //echo "client {$fd} closed,now client num:".count($this->client).'\n'; }); //05.小程序推送,实例不走nginx/apache,请访问本进程端口 $this->server->on('request', function ($request, $response) { //带有推送表示的主体 if(isset($request->post['status']) && $request->post['status']==1) { //接收小程序推送 $rev=array( 'type'=> $request->post['type'], 'shopid' =>$request->post['shopid'], 'orderid'=>$request->post['orderid'], ); $response->end('ok'); //直接尝试发送给点餐机 foreach ($this->client as $value) { if($value['shopid']==$rev['shopid']){ $data=json_encode($rev); $this->server->push($value['hostfd'],$data); break; } } //入列 array_push($this->clientmsg,$rev); } }); $this->server->start(); } } new WebsocketServer();
1、允许单个域名访问指定某域名(http://client.runoob.com)跨域访问,则只需在http://server.runoob.com/server.php文件头部添加如下代码:header('Access-Control-Allow-Origin:http://client....
主要原理是通过PHP创建多个子进程,在子进程中发送进程闹钟信号,然后再监听闹钟信号中继续发送闹钟信号。同时通过父进程设置非阻塞运行。代码如下:<?php /** * 订单任务 */ class Order { &n...
(1).学习的目标:学会创建父子进程,并且能够区分当前进程是父还是子;了解父进程执行过程,子进程执行过程;能够用多进程执行任务(2).相关函数学习: (2.1)pcntl_fork()执行时: &nbs...
<?php //如果支持exec函数,可以使用的方式 exec('chcp 65001'); //如果exec函数因安全问题禁用,可以使用的方式 pclose(popen('chcp 65001', 'r'));...
第一次听说端口复用是在mixphp最新版本中发现的,mixphp启动监听9501端口,现在作者说可以多开几个进程来执行mixphp,我心里想了下再启动不是会端口冲突嘛,但是却没有问题,于是下载mixphp的源码解读,原来是启动http服务器使用new Co\Http\Server('0.0....
php生成器的方法getReturn获取生成器迭代完成后的返回值,当生成器迭代完成会将生成器的返回值返回,因此如果迭代器未进行迭代是获取不到值的,如果你没有return值则返回null,参考代码:<?php function G1() { &nbs...