TP6+Swoole4 SOCKET事件處理

上一篇文章中講配置的時候其中的一個socket配置handler事件處理爲app\webscoket\Manager 類.下面來看下此類中須要完成那些方法php

socket監聽事件

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();
           }
      }

}
複製代碼

app\webscoket\Manager類內部結構

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的有效時間內刷新過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);
            }
        }
    });
}
複製代碼

Swoole\Server->isEstablished()

檢查是不是一個有效的websocket鏈接markdown

相關文章
相關標籤/搜索