基於 GatewayWorker 開發的 Laravel 擴充套件

i-am-king發表於2020-06-14

Laravel GatewayWorker

在專案開發的過程中,我使用了基於 workerman 開發的 GatewayWorker 擴充套件,為了與 Laravel 進行整合,翻看了一些相關的技術文章,但感覺都不太符合我心中想要的效果。為了能夠在 Laravel 中更優雅的使用 GatewayWorker 於是我自己造了個輪子,開發了 laravel-gateway-worker 擴充套件,使其能夠開箱即用,並可靈活配置和增加服務。

安裝

composer require smileymrking/laravel-gateway-worker

配置

Laravel

  1. config/app.php 註冊 ServiceProvider 和 Facade (Laravel 5.5 + 無需手動註冊)
'providers' => [
    // ...
    SmileyMrKing\GatewayWorker\GatewayWorkerServiceProvider::class,
];
  1. 建立配置檔案:
php artisan vendor:publish --provider="SmileyMrKing\GatewayWorker\GatewayWorkerServiceProvider"
  1. 修改應用根目錄下的 config/gateway-worker.php 中對應的配置即可。

Lumen

並未使用過 Lumen 未實際測試,以下參考其他擴充套件包編寫

  1. bootstrap/app.php 中 82 行左右:
$app->register(SmileyMrKing\GatewayWorker\GatewayWorkerServiceProvider::class);
  1. 釋出 config/gateway-worker.php 配置檔案,將 vendor/smileymrking/laravel-gateway-worker/config/gateway-worker.php 複製到專案根目錄/config目錄下。

配置檔案中已預設建立了一個名為 push 的 websocket 服務,配置如下,可自行調整相關配置,或無需釋出配置檔案,直接進入下一步啟動服務

return [

    /*
    |--------------------------------------------------------------------------
    | Gateway Worker Service
    |--------------------------------------------------------------------------
    */

    'default_service' => 'push', # 預設的 Gateway::$registerAddress 設定為 push.register_address

    'push' => [
        'service' => \SmileyMrKing\GatewayWorker\Push\Push::class,
        'lan_ip' => env('WS_LAN_IP', '127.0.0.1'), #內網ip,多伺服器分散式部署的時候需要填寫真實的內網ip

        'register' => env('WS_REGISTER', 'text://0.0.0.0:20000'),
        'register_address' => env('WS_REGISTER_ADDRESS', '127.0.0.1:20000'), #註冊服務地址

        'worker_name' => 'PushBusinessWorker', #設定 BusinessWorker 程式的名稱
        'worker_count' => 1, #設定 BusinessWorker 程式的數量
        # 設定使用哪個類來處理業務,業務類至少要實現onMessage靜態方法,onConnect 和 onClose 靜態方法可以不用實現
        'event_handler' => \SmileyMrKing\GatewayWorker\Push\PushEvent::class,

        'gateway' => env('WS_GATEWAY', 'websocket://0.0.0.0:20010'),# 允許連線服務的地址
        'gateway_name' => 'PushGateway', #設定 Gateway 程式的名稱,方便status命令中檢視統計
        'gateway_count' => 1, # Gateway 程式的數量
        'start_port' => env('WS_START_PORT', '20100'),  #監聽本機埠的起始埠
        'ping_interval' => 55,  # 心跳間隔時間,只針對服務端傳送心跳
        'ping_not_response_limit' => 1,   # 0 服務端主動傳送心跳, 1 客戶端主動傳送心跳
        'ping_data' => '{"type":"ping"}', # 服務端主動傳送心跳的資料,只針對服務端傳送心跳,客戶端超時未傳送心跳時會主動向客戶端傳送一次心跳檢測

        'gateway_start' => true,
        'business_worker_start' => true,
        'register_start' => true,

        'gateway_transport' => 'tcp', // 當為 ssl 時,開啟SSL,websocket+SSL 即 wss
        /*'gateway_context' => [
            // 更多ssl選項請參考手冊 http://php.net/manual/zh/context.ssl.php
            'ssl' => array(
                // 請使用絕對路徑
                'local_cert' => '/your/path/of/server.pem', // 也可以是crt檔案
                'local_pk' => '/your/path/of/server.key',
                'verify_peer' => false,
                'allow_self_signed' => true, //如果是自簽名證照需要開啟此選項
            )
        ],*/
    ],

];

啟動服務

使用以下命令啟動服務
php artisan gateway-worker {serviceName} {action} {--d}

引數 釋義
serviceName 服務名稱,即配置檔案中的鍵名
action 操作命令,可用命令有 statusstartstoprestartreloadconnections
--d 使用 DAEMON 模式
> php artisan gateway-worker push start

Workerman[gateway-worker push] start in DEBUG mode
----------------------------------------------- WORKERMAN -----------------------------------------------
Workerman version:4.0.6          PHP version:7.2.5-1+ubuntu18.04.1+deb.sury.org+1
------------------------------------------------ WORKERS ------------------------------------------------
proto   user            worker                listen                       processes    status
tcp     vagrant         PushGateway           websocket://0.0.0.0:20010    1             [OK]
tcp     vagrant         PushBusinessWorker    none                         1             [OK]
tcp     vagrant         Register              text://0.0.0.0:20000         1             [OK]
---------------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.

push 為預設建立的服務名稱,可同步釋出配置檔案,自行修改相關配置

建立多個服務

可同時啟動多個服務

參考 push 服務,手動建立一個 Demao 類,繼承 SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerService
定義一個 $serviceName 屬性,值為下一步所新增配置文的鍵名


namespace App\GatewayWorker\Demo;

use SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerService;

class Demo extends GatewayWorkerService
{
    protected $serviceName = 'demo';
}

直接複製一份 push 的配置檔案進行修改,注意需要修改 worker_namegateway_name 和相關埠的配置,避免重複
新增配置的鍵名為 上一步定義的 $serviceName 的值,配置中 service 執行上一步配置的 Demo 類

return [
    // ...
    'demo' => [
        'service' => \App\GatewayWorker\Demo\Demo::class,
        'lan_ip' => env('WS_LAN_IP_DEMO', '127.0.0.1'), #內網ip,多伺服器分散式部署的時候需要填寫真實的內網ip

        'register' => env('WS_REGISTER_DEMO', 'text://0.0.0.0:20000'),
        'register_address' => env('WS_REGISTER_ADDRESS_DEMO', '127.0.0.1:20000'), #註冊服務地址

        'worker_name' => 'DemoBusinessWorker', #設定 BusinessWorker 程式的名稱
        'worker_count' => 1, #設定 BusinessWorker 程式的數量
        # 設定使用哪個類來處理業務,業務類至少要實現onMessage靜態方法,onConnect 和 onClose 靜態方法可以不用實現
        'event_handler' => \App\GatewayWorker\Demo\DemoEvent::class,

        'gateway' => env('WS_GATEWAY_DEMO', 'websocket://0.0.0.0:20010'),# 允許連線服務的地址
        'gateway_name' => 'DemoGateway', #設定 Gateway 程式的名稱,方便status命令中檢視統計
        'gateway_count' => 1, # Gateway 程式的數量
        'start_port' => env('WS_START_PORT_DEMO', '20100'),  #監聽本機埠的起始埠
        'ping_interval' => 55,  # 心跳間隔時間,只針對服務端傳送心跳
        'ping_not_response_limit' => 1,   # 0 服務端主動傳送心跳, 1 客戶端主動傳送心跳
        'ping_data' => '{"type":"ping"}', # 服務端主動傳送心跳的資料,只針對服務端傳送心跳,客戶端超時未傳送心跳時會主動向客戶端傳送一次心跳檢測

        'gateway_start' => true,
        'business_worker_start' => true,
        'register_start' => true,

        'gateway_transport' => 'tcp', // 當為 ssl 時,開啟SSL,websocket+SSL 即 wss
        /*'gateway_context' => [
            // 更多ssl選項請參考手冊 http://php.net/manual/zh/context.ssl.php
            'ssl' => array(
                // 請使用絕對路徑
                'local_cert' => '/your/path/of/server.pem', // 也可以是crt檔案
                'local_pk' => '/your/path/of/server.key',
                'verify_peer' => false,
                'allow_self_signed' => true, //如果是自簽名證照需要開啟此選項
            )
        ],*/
    ],

];

配置修改完成後使用 php artisan gateway-worker demo start 命令啟動,demo 為剛剛配置的鍵名
event_handler 未配置時預設使用 SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerEvents ,實現了 onMessageonConnectonClose 三個靜態方法
可自定義 event_handler 類,需要繼承 SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerEvents 然後重寫相關靜態方法

namespace App\GatewayWorker\Demo;

use SmileyMrKing\GatewayWorker\GatewayWorker\GatewayWorkerEvents;

class DemoEvent extends GatewayWorkerEvents
{
    public static function onMessage($client_id, $message)
    {
        // Do something
    }
}

default_service 配置是指定 Gateway::$registerAddress 預設連線的哪個服務的註冊地址 register_address

訊息推送

可直接使用 GatewayWorker 中的 \GatewayWorker\Lib\Gateway 類,具體用法請檢視 GatewayWorker 手冊

日誌檢視

透過配置檔案中 service 項所配置的類的名稱空間檢視
push 服務的日誌檔案路徑為 vendor/smileymrking/laravel-gateway-worker/src/GatewayWorker/worker
日誌名稱為 smileymrking_gatewayworker_push_push.log

啟動程式 pid 檔案與日誌檔案路徑和名稱相同,字尾為 .pid

參考

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章