1. 程式人生 > 實用技巧 >【swoole】Laravel 框架使用 Swoole 程式碼熱更新

【swoole】Laravel 框架使用 Swoole 程式碼熱更新

業務背景

做的是一款遊戲匹配的 App,PHP 使用 swoole 建立 websocket 提供遊戲的匹配服務

匹配流程如下

  • 對匹配者的鑑權 (握手事件處理)
  • 匹配的業務邏輯 (比如男只能匹配到女,這塊也是需要熱更新,open 事件處理)
  • 匹配成功返回資料,關閉連線
  • 再往後就是 nodejs 去提供服務

想要達到的目的

在不重啟服務的情況下,改變了匹配的業務邏輯程式碼的情況下自動熱更新程式碼

關於熱更新 swoole 官方文件

其實核心就是說你要熱更新的程式碼必須在 onWorkerStart 事件中引入

安裝 swoole 和 inotify

自己繪製的 "設計圖"

如果你使用 artisan 啟動 swoole 服務的話,可能會熱更新失敗,因為在 onWorkerStart, 之前已經載入太多類

index

設定常量同時例項化 MatchServer 來啟動服務

require 'MatchServer.php';
if (php_sapi_name() != 'cli') die('請用cli模式啟動');
define('ROOT_PATH',dirname(dirname(dirname(__DIR__))).'/');
define('PORT',20005);
$server = new MatchServer();

MatchServer

class MatchServer{
    private $server;
    protected $application;

    function __construct ()
    {
        // 建立swoole_table,用於程序間資料共享
        $table = new swoole_table(1024);
        $table->column('fd', swoole_table::TYPE_INT);
        $table->column('uid', swoole_table::TYPE_INT);
        
$table->column('gameType', swoole_table::TYPE_STRING, 256); $table->column('data', swoole_table::TYPE_STRING, 256); $table->create(); $this->server = new swoole_websocket_server("0.0.0.0", PORT); $this->server->table = $table; // 註冊回撥事件 $this->server->on('handShake', array($this, 'onHandShake')); $this->server->on('workerStart', array($this, 'onWorkerStart')); $this->server->on('open', array($this, 'onOpen')); $this->server->on('message', array($this, 'onMessage')); $this->server->on('close', array($this, 'onClose')); $this->server->start(); } /** * 處理握手 * * @param swoole_http_request $request * @param swoole_http_response $response * * @return bool */ public function onHandShake (\swoole_http_request $request, \swoole_http_response $response) { if(引數校驗不通過) { $response->end(); return false; } //swoole握手環節,因為我的匹配是在open事件處理,當自己處理握手之後,不會自動呼叫open事件,需自己呼叫 // 握手環節程式碼..太多..考慮到篇幅問題,不貼了..大家可以去swoole手冊搜尋 $this->onOpen($this->server, $request); return true; } /** * 載入框架入口檔案,並設定inotify熱更新目錄 * * @param $server * @param $worker_id */ public function onWorkerStart ($server, $worker_id) { // 載入框架入口檔案 require ROOT_PATH.'public/index.php'; // 例項化業務邏輯類 $this->application = new MatchApplication(); if ($worker_id == 0) { // 設定熱更新目錄 $dir = app_path('Game/Match'); $list[] = $dir; foreach (array_diff(scandir($dir), array('.', '..')) as $item) { $list[] = $dir.'/'.$item; } $notify = inotify_init(); foreach ($list as $item) { inotify_add_watch($notify, $item, IN_CREATE | IN_DELETE | IN_MODIFY); } swoole_event_add($notify, function () use ($notify,$server) { $events = inotify_read($notify); if (!empty($events)) { // 執行swolle reload $server->reload(); } }); } } /** * 處理匹配 * * @param $server * @param $request */ public function onOpen ($server, $request) { // 呼叫業務邏輯類的onOpen $this->application->onOpen($server,$request); } public function onMessage ($server, $frame){} /** * 關閉連線同時刪除swoole_table資料 * * @param $server * @param $fd */ public function onClose ($server, $fd) { // 由於我程序間的資料共享用的swoole_table,所以連線關閉,需要刪除資料 if ($server->table->exist($fd)) { $server->table->del($fd); } } }

MatchApplication

/**
 * 處理匹配業務邏輯
 * 
 * @param $server
 * @param $request
 */
public function onOpen ($server, $request)
{
    $fd = $request->fd;
    // 處理業務邏輯......
    $server->push($fd,$data);
    $server->close($fd);
}

啟動服務

$ php Index.php

確認onWorkerStart之前沒有載入你要熱更新的程式碼

public function onWorkerStart ($server, $worker_id)
{
    print_r(get_included_files());
    return;
}


更多學習內容可以訪問【對標大廠】精品PHP架構師教程目錄大全,只要你能看完保證薪資上升一個臺階(持續更新)

以上內容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務程式碼寫多了沒有方向感,不知道該從那裡入手去提升,對此我整理了一些資料,包括但不限於:分散式架構、高可擴充套件、高效能、高併發、伺服器效能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell指令碼、Docker、微服務、Nginx等多個知識點高階進階乾貨需要的可以免費分享給大家,需要的可以點選連結領取進階PHP月薪30k>>>架構師成長路線【視訊、面試文件免費獲取】