swoole websocket服务推送
用过workerman, 两个字"好用",对于swoole最近有时间也研究研究
swoole的websocket 很好实现
如官网 https://wiki.swoole.com/wiki/page/479.html
ws_server.php
//创建websocket服务器对象,监听0.0.0.0:9502端口 $ws = new swoole_websocket_server("0.0.0.0", 9502); //监听WebSocket连接打开事件 $ws->on('open', function ($ws, $request) { var_dump($request->fd, $request->get, $request->server); $ws->push($request->fd, "hello, welcome\n"); }); //监听WebSocket消息事件 $ws->on('message', function ($ws, $frame) { echo "Message: {$frame->data}\n"; $ws->push($frame->fd, "server: {$frame->data}"); }); //监听WebSocket连接关闭事件 $ws->on('close', function ($ws, $fd) { echo "client-{$fd} is closed\n"; }); $ws->start();
运行程序
php ws_server.php
客户端 a.html
var wsServer = 'ws://127.0.0.1:9502'; var websocket = new WebSocket(wsServer); websocket.onopen = function (evt) { console.log("Connected to WebSocket server."); }; websocket.onclose = function (evt) { console.log("Disconnected"); }; websocket.onmessage = function (evt) { console.log('Retrieved data from server: ' + evt.data); }; websocket.onerror = function (evt, e) { console.log('Error occured: ' + evt.data); };
ok了!
现在我们看到的是客户端发送信息,服务器应答并返回数据
那我们现在要的是服务器主动发送信息
有三个办法:
1.使用swoole的定时器,定时发送,可通过syc从数据库获取数据逻辑判断后push发送给客户端
2.使用swoole中自带框架
这个方法和方法3原理是一样的,就是需要后台主动推送的时候,模拟一个客户端发送消息,可以是CLI的脚本,也可以是php的CURL请求
https://github.com/matyhtf/framework/blob/master/libs/Swoole/Client/WebSocket.php
github下载地址:https://wiki.swoole.com/wiki/page/397.html
swoole_websocket_server 继承自 swoole_http_server
|
代码如下
ser.php
<?php class MyWebsocket { private $server; private $fid=[]; # run() public function toRun() { $this->server = new swoole_websocket_server("0.0.0.0", 9502, SWOOLE_BASE, SWOOLE_SOCK_TCP); //SWOOLE_SSL 需要ssl才加 #监听WebSocket连接打开事件 $this->server->on('open', function ($server, $request) { $this->server->push($request->fd, "hello, welcome ID:{$request->fd}\n"); $this->fid[]=$request->fd; # $request->fd fd }); #监听WebSocket消息事件 $this->server->on('message', function ($server, $frame) { #$frame->data 消息内容 $msg = 'from' . $frame->fd . ":{$frame->data}\n"; foreach ($this->fid as $fd) { $server->push($fd, $msg); } }); //监听WebSocket连接关闭事件 $this->server->on('close', function($ws, $fd) { $fd_key = array_search($fd, $this->fid ? $this->fid : []); $key_zero = isset($this->fid[0]) && $this->fid[0] == $fd ? TRUE : FALSE; # key=0 if ($fd_key || $key_zero) { unset($this->fid[$fd_key]); } echo "client-{$fd} is closed\n"; }); #onRequest回调 http://127.0.0.1:9502/?sendto=1,20,3&message=%E4%BD%A0%E5%A5%BD $this->server->on('request', function ($req, $respone) { # get 两个参数, userid "," 发送消息 $list=[]; if (isset($req->get['sendto']) && isset($req->get['message'])) { $user = explode(',', $req->get['sendto']); $list = array_intersect($this->fid, $user); if (!empty($list)) { foreach ($list as $fd) { $this->server->push($fd, $req->get['message']); } } } $total= count($this->fid); $sendSum= count($list); $respone->end("Current fid:{$respone->fd}, OnLine:{$total}, Send:{$sendSum}"); }); $this->server->start(); } } $app = new MyWebsocket(); $app->toRun();
客户端html
Title
运行
php ser.php