上一篇文章中講配置的時候其中的一個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