上一篇文章中讲配置的时候其中的一个socket
配置handler
事件处理为app\webscoket\Manager
类.下面来看下此类中须要完成那些方法php
app\event.phpreact
return [
'listen' => [
'swoole.workerStart' => [\app\websocket\SwooleWorkerStart::class],//socket启动事件
'swoole.workerStop' => [],//socket中止事件
'swoole.workerError' => [],//socket发生错误事件
'swoole.workerExit' => [],//仅在异步重启后执行事件
]
];
复制代码
SwooleWorkerStart 类内部结构web
<?php
namespace app\webscoket;
class SwooleWorkerStart
{
public function __construct()
{
} // 事件执行 $event 为对象think\swoole\App实例化后的结果
public function handle($event): void
{
if ($event->make('swoole.server')->worker_id === 0 &&
$event->config->get('swoole.websocket.enable',false)) {
//只有再0号进程上监听socket启动事件
//而且socket已经启动了才执行事件
//socket的ping事件
$this->ping();
//定时任务
$this->timer();
}
}
}
复制代码
swoole.php配置中的websocket.handle 一旦被从新配置,类被重写那么本来内置的事件会丢失须要自行处理数据库
<?php
namespace app\webscoket;
use think\swoole\Websocket;
use Swoole\Websocket\Frame;
class Manager extends Websocket
{
/**
* 启动事件
* "onOpen" listener.
*
* @param int $fd
* @param Request $request
*/
public function onOpen($fd, \think\Request $request)
{
//能够写长链接受权的逻辑
//受权不经过调用 $this->server->close($fd);关闭链接
//$request->get()能获取到长链接携带的参数
//登录成功能够用push方法推送消息到前台
//$this->server->push($fd, $data);
}
/**
* 消息接收事件
* "onMessage" listener.
*
* @param Frame $frame
*/
public function onMessage(Frame $frame)
{
//$frame->fd 为当前链接惟一值
//$frame->data 为当前消息内容
//能够根据消息内容作出对应的消息处理逻辑
//消息的内容可以下
//{"type":"test","data":{"message":"你好呀"}}
//而后根据type可调用不一样的事件或者方法来处理消息
}
/**
* 关闭事件
* "onClose" listener.
*
* @param int $fd 链接fd
* @param int $reactorId 线程id
*/
public function onClose($fd, $reactorId)
{
//这里主要处理某个链接关闭后的事件,告知其余人或者修改数据库让当前链接对应的用户下线
}
}
复制代码
思路就是启动一个定时器不停的监听当前链接的用户是否再ping的有效时间内刷新过ping若是没有那就调用app('swoole.server')->close($fd)
来关闭它websocket
此方法写在 SwooleWorkerStart
类中swoole
use Swoole\Timer;
protected function ping()
{
Timer::tick(1500, function (int $timer_id) {
/** @var Swoole\Server $server*/
$server = app('swoole.server');
foreach ($server->connections as $fd) {
if ($server->isEstablished($fd)) {
//能够利用内存数据库把$fd相关的用户信息和链接过时时长记录下来
//而后来判断是否要关闭这个链接
//关闭: $server->close($fd);
}
}
});
}
复制代码
检查是不是一个有效的websocket链接markdown