【Laravelと連携する】

はじめに

ここでは新規プロジェクトを連携する場合と既成プロジェクトを連携する場合に分けて話を進めます。
それぞれの作業の内訳は以下の通りです。

【新規プロジェクトを連携する場合】

ステップ1)ライブラリをインストール
ステップ2)workerコマンドをコピー

【既成プロジェクトを連携する場合】

さらに以下2ステップが必要です。
ステップ3)既成クラスをコピー
ステップ4)既成のメインクラスをLaravelのCommandクラスへ変換
ステップ5)設定系ファイルのコピー【任意】

新規プロジェクトを連携


ステップ1)ライブラリをインストール

Laravelのプロジェクトルートで以下のコマンドを実行すればインストールできます。
socket-managerライブラリをインストールするコマンド
> composer require socket-manager/library
                    

ステップ2)workerコマンドをコピー

workerコマンドをLaravelのプロジェクトルートへコピーします。
コマンドでコピーする場合はLaravelのプロジェクトルートへ移動してから以下のコマンドを実行してください。
workerコマンドをコピーするコマンド
> cp ./vendor/socket-manager/library/bin/worker .
                    

コピーが完了するとworkerコマンドはLaravelのartisanコマンドと自動で連携します。
Usageを確認すると以下のように表示されます。
Usage表示
> php worker
SOCKET-MANAGER Framework 1.0.0
Usage:
  command [arguments]

 craft
  craft:init <初期化クラス名>                     初期化クラスの生成
  craft:parameter <UNITパラメータクラス名>        UNITパラメータクラスの生成
  craft:protocol <プロトコルUNIT定義のクラス名>   プロトコルUNIT定義のクラスとステータス名Enumの生成
  craft:command <コマンドUNIT定義のクラス名>      コマンドUNIT定義のクラスとキュー/ステータス名Enumの生成
  craft:main <メイン処理のクラス名>               メイン処理クラスの生成
 laravel
  laravel:command <メイン処理のクラス名>          Laravelコマンドクラスの生成

--------------------------------------------------------------------------------
Laravel Framework 10.48.10

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display help for the given command. When no command is given display help for the list command
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi|--no-ansi  Force (or disable --no-ansi) ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env[=ENV]       The environment the command should run under
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  about                   Display basic information about your application
  clear-compiled          Remove the compiled class file
  completion              Dump the shell completion script
  db                      Start a new database CLI session
  docs                    Access the Laravel documentation
  down                    Put the application into maintenance / demo mode
  env                     Display the current framework environment
  help                    Display help for a command
  inspire                 Display an inspiring quote
  list                    List commands
  migrate                 Run the database migrations
  optimize                Cache the framework bootstrap files
  serve                   Serve the application on the PHP development server
  test                    Run the application tests
  tinker                  Interact with your application
  up                      Bring the application out of maintenance mode
 auth
  auth:clear-resets       Flush expired password reset tokens
 cache
  cache:clear             Flush the application cache
  cache:forget            Remove an item from the cache
  cache:prune-stale-tags  Prune stale cache tags from the cache (Redis only)
  cache:table             Create a migration for the cache database table
 channel
  channel:list            List all registered private broadcast channels
 config
  config:cache            Create a cache file for faster configuration loading
  config:clear            Remove the configuration cache file
  config:show             Display all of the values for a given configuration file
 db
  db:monitor              Monitor the number of connections on the specified database
  db:seed                 Seed the database with records
  db:show                 Display information about the given database
  db:table                Display information about the given database table
  db:wipe                 Drop all tables, views, and types
 env
  env:decrypt             Decrypt an environment file
  env:encrypt             Encrypt an environment file
 event
  event:cache             Discover and cache the application's events and listeners
  event:clear             Clear all cached events and listeners
  event:generate          Generate the missing events and listeners based on registration
  event:list              List the application's events and listeners
 key
  key:generate            Set the application key
 lang
  lang:publish            Publish all language files that are available for customization
 make
  make:cast               Create a new custom Eloquent cast class
  make:channel            Create a new channel class
  make:command            Create a new Artisan command
  make:component          Create a new view component class
  make:controller         Create a new controller class
  make:event              Create a new event class
  make:exception          Create a new custom exception class
  make:factory            Create a new model factory
  make:job                Create a new job class
  make:listener           Create a new event listener class
  make:mail               Create a new email class
  make:middleware         Create a new middleware class
  make:migration          Create a new migration file
  make:model              Create a new Eloquent model class
  make:notification       Create a new notification class
  make:observer           Create a new observer class
  make:policy             Create a new policy class
  make:provider           Create a new service provider class
  make:request            Create a new form request class
  make:resource           Create a new resource
  make:rule               Create a new validation rule
  make:scope              Create a new scope class
  make:seeder             Create a new seeder class
  make:test               Create a new test class
  make:view               Create a new view
 migrate
  migrate:fresh           Drop all tables and re-run all migrations
  migrate:install         Create the migration repository
  migrate:refresh         Reset and re-run all migrations
  migrate:reset           Rollback all database migrations
  migrate:rollback        Rollback the last database migration
  migrate:status          Show the status of each migration
 model
  model:prune             Prune models that are no longer needed
  model:show              Show information about an Eloquent model
 notifications
  notifications:table     Create a migration for the notifications table
 optimize
  optimize:clear          Remove the cached bootstrap files
 package
  package:discover        Rebuild the cached package manifest
 queue
  queue:batches-table     Create a migration for the batches database table
  queue:clear             Delete all of the jobs from the specified queue
  queue:failed            List all of the failed queue jobs
  queue:failed-table      Create a migration for the failed queue jobs database table
  queue:flush             Flush all of the failed queue jobs
  queue:forget            Delete a failed queue job
  queue:listen            Listen to a given queue
  queue:monitor           Monitor the size of the specified queues
  queue:prune-batches     Prune stale entries from the batches database
  queue:prune-failed      Prune stale entries from the failed jobs table
  queue:restart           Restart queue worker daemons after their current job
  queue:retry             Retry a failed queue job
  queue:retry-batch       Retry the failed jobs for a batch
  queue:table             Create a migration for the queue jobs database table
  queue:work              Start processing jobs on the queue as a daemon
 route
  route:cache             Create a route cache file for faster route registration
  route:clear             Remove the route cache file
  route:list              List all registered routes
 sail
  sail:add                Add a service to an existing Sail installation
  sail:install            Install Laravel Sail's default Docker Compose file
  sail:publish            Publish the Laravel Sail Docker files
 sanctum
  sanctum:prune-expired   Prune tokens expired for more than specified number of hours
 schedule
  schedule:clear-cache    Delete the cached mutex files created by scheduler
  schedule:interrupt      Interrupt the current schedule run
  schedule:list           List all scheduled tasks
  schedule:run            Run the scheduled commands
  schedule:test           Run a scheduled command
  schedule:work           Start the schedule worker
 schema
  schema:dump             Dump the given database schema
 session
  session:table           Create a migration for the session database table
 storage
  storage:link            Create the symbolic links configured for the application
  storage:unlink          Delete existing symbolic links configured for the application
 stub
  stub:publish            Publish all stubs that are available for customization
 vendor
  vendor:publish          Publish any publishable assets from vendor packages
 view
  view:cache              Compile all of the application's Blade templates
  view:clear              Clear all compiled view files
                    
craft:settingcraft:localeコマンドに関してはLaravel環境では表示されません。

Usageのハイフン線の上側でworkerコマンドのUsageが、下側でartisanコマンドのUsageが表示されていれば連携は完了です。
あとはworkerコマンドで随時必要なクラスを生成していく事になります。

但し、メインクラスの作成に関してはLaravelのバッチ処理として登録する必要があるので以下のコマンド実行が必要です。
コマンドクラス名をMainForTestにする場合
> php worker laravel:command MainForTest

[success] メイン処理クラスの生成に成功しました (MainForTest)
[success] Laravelコマンドクラスの生成に成功しました (MainForTest)
                    

このコマンドを実行するとapp/MainClass/MainForTest.phpapp/Console/Commands/MainForTest.phpが作成されます。
その後Usageを表示するとLaravelのUsage側で以下のように表示されます。
Usage表示
> php worker
.
.
.
 app
  app:main-for-test       Command description
.
.
.
                    

サーバー起動はいつも通りの以下コマンドで実行できます。
サーバー起動(10000ポートで起動する場合)
> php worker app:main-for-test 10000
                    

既成プロジェクトを連携


ステップ3)既成クラスをコピー

app配下の既成クラスはLaravelのapp配下にディレクトリごとコピーしてください。
logsディレクトリはLaravelのプロジェクトルートにコピーする必要があります。

ステップ4)既成のメインクラスをLaravelのCommandクラスへ変換

既成のメインクラスはそのままでは使えないので以下のコマンドを実行してLaravelのコマンドクラスへ変換できます。
デモ版のWebsocketサーバーを変換する場合
> php worker laravel:command ChatServerForWebsocket

[success] Laravelコマンドクラスの生成に成功しました (ChatServerForWebsocket)
                    

この時app/MainClass内のファイルはそのまま残ります。
その後Usageを表示するとLaravelのUsage側で以下のように表示されます。
Usage表示
> php worker
.
.
.
 app
  app:chat-server         チャットサーバー
.
.
.
                    

サーバー起動はいつも通りの以下コマンドで実行できます。
サーバー起動(10000ポートで起動する場合)
> php worker app:chat-server 10000
                    

ステップ5)設定系ファイルのコピー【任意】

定数やメッセージなどの設定系のファイルを利用されている場合は適宜Laravel環境へコピーしてください。
設定値を取得するヘルパー関数の仕様はLaravelに合わせてあるのでソースを変更する必要はありません。

対応するディレクトリの名前は次の通りです。
・setting(socket-manager用) ⇒ config(laravel用)
・locale(socket-manager用) ⇒ lang(laravel用)
※ディレクトリごとファイルを上書きしてしまう事故を防ぐためにディレクトリ名は敢えて異なるものを採用しています。
※重複しているファイル名がある場合は設定内容をご自身の目で確認しながらマージを行ってください。
setting/app.phpファイルにはタイムゾーンやロケールなどシステムに関わる内容が含まれています。基本的にはLaravelのconfig/app.phpの内容と同じはずですが念のため内容を確認される事をお勧めします。

Laravelのリソースを使う

Laravelとの連携が完了した事で今後はLaravelのリソースが使えるようになります。
せっかくなのでログ出力をLaravelのLoggerを使って出力してみます。
以降ではデモ版のWebsocketサーバーを使います。

まずは初期化クラス内でuse Illuminate\Support\Facades\Log;を追加した上でlogWriterハンドラーを以下のように修正します。
以下の黄色の部分が追加したソースで、コメントで囲んでいる部分が元のソースです。
app/InitClass/InitForWebsocket.php
public function getLogWriter()
{
    return function(string $p_level, array $p_param)
    {
        Log::channel('socket-manager-log')->{$p_level}('TEST', ['param' => $p_param]);

        /*
        $filename = date('Ymd');
        $now = date('Y-m-d H:i:s');
        $log = $now." {$p_level} ".print_r($p_param, true)."\n";
        error_log($log, 3, "./logs/socket-manager-log/{$filename}_W{$this->port}.log");
        */
    };
}
                    

Laravelのconfig/logging.php内で以下の定義を追加してサーバー起動します。
config/logging.php
'socket-manager-log' => [
    'driver' => 'daily',
    'path' => storage_path('logs/bat/socket-manager-log/laravel.log'),
    'level' => 'debug',
    'days' => 0,
],
                    
デモ版Websocketサーバー起動(10000ポートで起動する場合)
> php worker app:chat-server 10000
                    

クライアントと接続すると以下の場所にログファイルが作成されます。
ログファイルの出力先
/storage
    /logs
        /bat
            /socket-manager-log
                laravel-<日付フォーマット("Y-m-d")>.log
                    

おわりに

これでWebアプリとソケット通信サーバーのオールインワン開発環境ができました。
上記ではLaravelのログ出力を試しましたが、他にも色々使えるはずですので試してみてください。

生のPHP環境でデータベースを使う場合は標準のPDOライブラリ等を使う事が多いと思いますが、フレームワークの作業に慣れている方はEloquentやクエリビルダ等を使ってデータベースと連携した方が使いやすいでしょう。