环境配置:
swoole 1.9.3、centos6.5(虚拟机)、PHP7.01
思路:
①通过server中的collections取出fd
②写一个admin.html(管理员推送页面) 与 client.html(客户端),html页面的websocket自行可编写
并在server.php中message事件用循环push数据(server中的collections取出fdfd组)
$serv->on('Message', function ($server, $frame) { echo " message: " . $frame->data . " "; foreach ($server->connections as $key => $value) { if($frame->fd != $value){ $server->push($value, "客户{$value}:".$frame->data); } } });
注:其实这里需要admin.html发送数据时传token并在message事件中验证是否管理员请求(数据库操作),是才执行推送,否则不做操作
server.php代码如下:
<?php $serv = new SwooleWebsocketServer("0.0.0.0", 9502); $serv->on('Open', function ($server, $req) { echo " connection open: " . $req->fd . " "; }); $serv->on('Message', function ($server, $frame) { echo " message: " . $frame->data . " "; foreach ($server->connections as $key => $value) { if($frame->fd != $value){ $server->push($value, "客户{$value}:".$frame->data); } } }); $serv->on('Close', function ($server, $fd) { echo " connection close: " . $fd; }); $serv->start();
效果图:
注:客户端websocket自行编写。
上面推送小实例实现中有点问题,并未将客户端与服务端分离开来,以下分离开。
因为swoole_websocket_server 继承自 swoole_http_server,所以可在websocket中用Request事件,另外用global引入用于在Request事件中push
①首先admin.html改为http请求,且client.html保持不变
<form method="post" action="http://localhost:9502/server.php"> <input name="test" type="text" placeholder="please input something"> <input type="submit" value="submit"> </form>
②将Message事件的push部分删掉,如下:
$serv->on('Message', function ($server, $frame) use($redis) { echo " message: " . $frame->data . " "; //将来可用于写数据库信息 });
③添加http的Request事件,如下:
//服务端请求更新数据,这里是http方式 $serv->on('Request', function ($req, $respone) { global $serv; //全局引入$serv global $redis; //全局引入redis print_r($req->post); if(count($req->post)){ //判断下是否有数据 foreach (@$serv->connections as $key => $value) { @$serv->push($value, "客户{$value}:".$req->post["test"]); } $respone->end("success"); } });