はじめに
この環境では基本的なディレクトリ構成とライブラリしか入っていませんので、真っ新な状態から開発を始められます。
ランタイムライブラリ(RuntimeManager)を使った常駐型アプリのみの実装では、SocketManagerクラスを使う場合に比べてプロトコル部を作成する必要がなくなるので、より簡易的な実装になります。
ここでは、環境のインストール手順とphp worker
コマンドを使った新規のクラスを生成するコマンドをご紹介します。
インストール
開発環境は、以下のコマンドでインストールできます。
> composer create-project socket-manager/new-project <インストール先のディレクトリ名>
インストールが完了すると、以下のディレクトリ構成で展開されます。
/app
/InitClass 初期化クラス用
/UnitParameter UNITパラメータクラス用
/ProtocolUnits プロトコルUNIT定義クラス用
/CommandUnits コマンドUNIT定義クラス用
/MainClass メイン処理クラス用
/logs ログ出力用
/setting 設定ファイル用
php worker
コマンドを実行すると以下のようなUsageが表示されます。
> php worker
SOCKET-MANAGER Framework 1.16.0
Usage:
command [arguments]
main
Empty...
craft
craft:init <初期化クラス名> 初期化クラスの生成
craft:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
craft:protocol <プロトコルUNIT定義のクラス名> プロトコルUNIT定義のクラスとステータス名Enumの生成
craft:command <コマンドUNIT定義のクラス名> コマンドUNIT定義のクラスとキュー/ステータス名Enumの生成
craft:main <メイン処理のクラス名> メイン処理クラスの生成
craft:setting <設定ファイル名> 設定ファイルの生成
craft:locale <メッセージファイル名> メッセージファイルの生成
runtime
runtime:init <初期化クラス名> 初期化クラスの生成
runtime:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
runtime:units <ランタイムUNIT定義のクラス名> ランタイムUNIT定義のクラスとキュー/ステータス名Enumの生成
runtime:main <メイン処理のクラス名> メイン処理クラスの生成
laravel:command
コマンドに関してはLaravel環境でしか表示されません。
それでは動作確認のため、以下のコマンドを実行してメイン処理クラスを作成します。
今回はMainForTest
という名前で作成します。
以下のように表示されれば成功です。
> php worker runtime:main MainForTest
[success] メイン処理クラスの生成に成功しました (MainForTest)
再度php worker
を実行してみます。
> php worker
SOCKET-MANAGER Framework 1.16.0
Usage:
command [arguments]
main
app:main-for-test Command description
craft
craft:init <初期化クラス名> 初期化クラスの生成
craft:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
craft:protocol <プロトコルUNIT定義のクラス名> プロトコルUNIT定義のクラスとステータス名Enumの生成
craft:command <コマンドUNIT定義のクラス名> コマンドUNIT定義のクラスとキュー/ステータス名Enumの生成
craft:main <メイン処理のクラス名> メイン処理クラスの生成
craft:setting <設定ファイル名> 設定ファイルの生成
craft:locale <メッセージファイル名> メッセージファイルの生成
runtime
runtime:init <初期化クラス名> 初期化クラスの生成
runtime:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
runtime:units <ランタイムUNIT定義のクラス名> ランタイムUNIT定義のクラスとキュー/ステータス名Enumの生成
runtime:main <メイン処理のクラス名> メイン処理クラスの生成
アプリ名main-for-test
という名前で登録されている事が確認できれば正常にインストールされています。
初期化クラスの実装
初期化クラスのソースは以下のコマンドで作成できます。
InitForTest
という名前で作成する場合、以下のように表示されれば成功です。
> php worker runtime:init InitForTest
[success] 初期化クラスの生成に成功しました (InitForTest)
/app
/InitClass
InitForTest.php
/**
* RuntimeManager初期化クラス
*
* IInitRuntimeManagerインタフェースをインプリメントする
*/
class InitForTest implements IInitRuntimeManager
{
/**
* コンストラクタ
*
*/
public function __construct()
{
}
/**
* ログライターの取得
*
* nullを返す場合は無効化(但し、ライブラリ内部で出力されているエラーメッセージも出力されない)
*
* @return mixed "function(string $p_level, array $p_param): void" or null(ログ出力なし)
*/
public function getLogWriter()
{
return null;
}
/**
* 緊急停止時のコールバックの取得
*
* 例外等の緊急停止時に実行される。nullを返す場合は無効化となる。
*
* @return mixed "function(RuntimeManagerParameter $p_param)"
*/
public function getEmergencyCallback()
{
return null;
}
/**
* UNITパラメータインスタンスの取得
*
* nullの場合はRuntimeManagerParameterのインスタンスが適用される
*
* @return ?RuntimeManagerParameter RuntimeManagerParameterクラスのインスタンス(※1)
* @see:RETURN (※1)当該クラス、あるいは当該クラスを継承したクラスも指定可
*/
public function getUnitParameter(): ?RuntimeManagerParameter
{
return new RuntimeManagerParameter();
}
}
ここでは以下の IInitRuntimeManager インターフェースメソッドを実装します。
各々のメソッドではnullを返す事で無効化できます。
- ■getLogWriterメソッドの実装
-
ライブラリ内でのログ出力に利用。
ハンドラーにする事でerror_log
関数やフレームワークのLogger
等の利用が可能。 - ■getEmergencyCallbackメソッドの実装
- ステータスUNITで例外発生時に処理すべき内容がコールされる。
- ■getUnitParameterメソッドの実装
- UNITパラメータとして利用される。グローバルエリアの管理が必要ないのであれば
RuntimeManagerParameter
クラスをそのまま使っても構わない。
初期化クラスの実装内容の詳細については、以下のページをご覧ください。
ランタイムUNITクラスの実装
このクラスは以下のコマンドで作成できます。
RuntimeForTest
という名前で作成する場合、以下のように表示されれば成功です。
> php worker runtime:units RuntimeForTest
[success] ランタイムUNITクラスの生成に成功しました (RuntimeForTest)
[success] ランタイムUNITのキュー名Enumの生成に成功しました (RuntimeForTestQueueEnum)
[success] ランタイムUNITのステータス名Enumの生成に成功しました (RuntimeForTestStatusEnum)
/app
/RuntimeUnits
RuntimeForTest.php
RuntimeForTestQueueEnum.php
RuntimeForTestStatusEnum.php
/**
* ランタイムUNIT登録クラス
*
* IEntryUnitsインタフェースをインプリメントする
*/
class RuntimeForTest implements IEntryUnits
{
/**
* @var const QUEUE_LIST キュー名のリスト
*/
protected const QUEUE_LIST = [
RuntimeForTestQueueEnum::STARTUP->value // 起動処理のキュー
];
/**
* コンストラクタ
*
*/
public function __construct()
{
}
/**
* キューリストの取得
*
* @return array キュー名のリスト
*/
public function getQueueList(): array
{
return (array)static::QUEUE_LIST;
}
/**
* ステータスUNITリストの取得
*
* @param string $p_que キュー名
* @return array キュー名に対応するUNITリスト
*/
public function getUnitList(string $p_que): array
{
$ret = [];
if($p_que === RuntimeForTestQueueEnum::STARTUP->value)
{
$ret[] = [
'status' => RuntimeForTestStatusEnum::START->value,
'unit' => $this->getStartupStart()
];
}
return $ret;
}
/**
* 以降はステータスUNITの定義("STARTUP"キュー)
*/
/**
* ステータス名: START
*
* 処理名:起動処理開始
*
* @param RuntimeManagerParameter $p_param UNITパラメータ
* @return ?string 遷移先のステータス名
*/
protected function getStartupStart()
{
return function(RuntimeManagerParameter $p_param): ?string
{
$p_param->logWriter('debug', ['STARTUP' => 'START']);
return null;
};
}
}
ここでは以下の IEntryUnits インターフェースメソッドを実装します。
- ■getQueueListメソッドの実装
- ランタイムUNITクラスで利用するキューのリストを返す
- ■getUnitListメソッドの実装
- 引数のキュー名に対応するUNITのリストを返す
- ■各UNITの実装
-
getUnitList
メソッドで返している定義済みのUNIT処理を実装
UNIT本体の処理は上記の場合getStartupStart
メソッドでクロージャとして返していますが、グローバル関数名を指定する事も可能です。
ランタイムUNITクラスで利用するキュー名はライブラリ側のRuntimeQueueEnum
クラスで予約されています。
enum RuntimeQueueEnum: string
{
/**
* @var 起動時のキュー名
*/
case STARTUP = 'startup';
}
ランタイムUNITクラスの実装内容の詳細については、以下のページをご覧ください。
予約済ステータス
予約されているものは以下ライブラリ側のEnum定義のみです。
enum StatusEnum: string
{
/**
* @var UNITの処理開始時のステータス名
*/
case START = 'start';
}
UNITパラメータクラスの実装
UNITパラメータクラスのソースは以下のコマンドで作成できます。
ParameterForTest
という名前で作成する場合、以下のように表示されれば成功です。
> php worker runtime:parameter ParameterForTest
[success] UNITパラメータクラスの生成に成功しました (ParameterForTest)
/app
/UnitParameter
ParameterForTest.php
ここで述べているUNITパラメータというのはランタイムUNITで定義されているUNITの引数の部分です。
上記のランタイムUNITの例でいえばRuntimeManagerParameter $p_param
の部分になります。
この引数にはRuntimeManagerParameter
クラスを継承しているものであれば何を指定しても構いません。
グローバルエリアを使う必要がなければ特に実装する事は何もありませんが、新規で作成した場合は以下のようにUNIT処理の引数の部分を必要に応じて置き替えてください。
protected function getStartupStart()
{
return function(RuntimeManagerParameter $p_param): ?string
{
$p_param->logWriter('debug', ['STARTUP' => 'START']);
return null;
};
}
protected function getStartupStart()
{
return function(ParameterForTest $p_param): ?string
{
$p_param->logWriter('debug', ['STARTUP' => 'START']);
return null;
};
}
UNITパラメータクラスの実装内容の詳細については以下のページをご覧ください。
メイン処理クラスの実装
メイン処理クラスのソースは以下のコマンドで作成できます。
MainForTest
という名前で作成する場合、以下のように表示されれば成功です。
> php worker runtime:main MainForTest
[success] メイン処理クラスの生成に成功しました (MainForTest)
/app
/MainClass
MainForTest.php
生成されるソースは次の通り。
class MainForTest extends Console
{
/**
* @var string $identifer アプリケーション識別子
*/
protected string $identifer = 'app:main-for-test';
/**
* @var string $description コマンド説明
*/
protected string $description = 'Command description';
/**
* アプリケーション起動
*
*/
public function exec()
{
// ランタイムマネージャーのインスタンス設定
$manager_runtime = new RuntimeManager();
/***********************************************************************
* ランタイムマネージャーの初期設定
*
* ランタイムUNITクラス等のインスタンスをここで設定します
**********************************************************************/
/**
* 初期化クラスの設定
*
* $manager_runtime->setInitRuntimeManager()メソッドで初期化クラスを設定します
*/
/**
* ランタイムUNITの設定
*
* $manager_runtime->setRuntimeUnits()メソッドでランタイムUNITクラスを設定します
*/
/***********************************************************************
* ランタイムマネージャーの実行
*
* 周期ドリブン処理を実行します
**********************************************************************/
// ノンブロッキングループ
while(true)
{
// 周期ドリブン
$ret = $manager_runtime->cycleDriven();
if($ret === false)
{
goto finish;
}
}
finish:
return;
}
}
ここで実装が必要になるのは初期設定ブロックである以下の2点になります。
- ■初期化クラスの設定
- 初期化クラスのインスタンスを生成し、
RuntimeManager
クラスのsetInitRuntimeManager
メソッドにインスタンスを引き渡す - ■ランタイムUNITの設定
- ランタイムUNITクラスのインスタンスを生成し、
RuntimeManager
クラスのsetRuntimeUnits
メソッドにインスタンスを引き渡す
メイン処理クラスの実装内容の詳細については、以下のページをご覧ください。
設定ファイルの作成
設定ファイルは以下のコマンドで作成できます。
test
という名前で作成する場合、以下のように表示されれば成功です。
> php worker craft:setting test
[success] 設定ファイルの生成に成功しました (test)
/setting
test.php
作成されるソースは次の通り、空の配列のリターン値になります。
return [
];
使い方
設定ファイル内の設定値を取得するヘルパー関数はLaravelと同様に使えるようにしています。
ここではtest_key
という名前の設定名を使って値を取得する場合を例に挙げます。
設定ファイルで以下のように連想配列を定義していたとします。
return [
'test_key' => 100
];
あとはプログラムの方でconfig
ヘルパー関数を使って以下のように取得するだけです。
$value = config('test.test_key', null);
変数$value
には100を返します。
関数の第一引数にはファイル名を含めたキー名をピリオド区切りで指定します。第二引数には値が取得できなかった場合のデフォルト値を指定します。
メッセージファイルの作成
メッセージ管理のコマンドはsetting/app.php
内のlocale
設定項目と連動します。
例えばlocale
の項目がja
の場合の挙動は以下の通りです。
> php worker craft:locale test
[success] メッセージファイルの生成に成功しました (test)
/locale
/ja
test.php
test.php
のファイルはja
のサブディレクトリに格納されます。
作成されるソースは次の通り、空の配列のリターン値になります。
return [
];
使い方
メッセージファイル内のメッセージを取得するヘルパー関数はLaravelと同様に使えるようにしています。
ここではtest_key
という名前の設定名を使って値を取得する場合を例に挙げます。
メッセージファイルで以下のように連想配列を定義していたとします。
return [
'test_key' => 'テストメッセージ'
];
あとはプログラムの方で__
ヘルパー関数を使って以下のように取得するだけです。
$value = __('test.test_key');
変数$value
には「テストメッセージ」という文字列を返します。
また、以下のようにプレースホルダも使えます。
return [
'test_key' => '私の名前は:nameです。年齢は:age歳です。'
];
$value = __('test.test_key', ['name' => '山田太郎', 'age' => 20]);
変数$value
には「私の名前は山田太郎です。年齢は20歳です。」という文字列を返します。
おわりに
動作確認をしながら進めるのであれば以下の順に進めるのがいいでしょう。
- 1.初期化クラスの実装
- 2.メイン処理クラスの実装
- 3.ランタイムUNITクラスの実装
初期化クラスを実装後は、ログライターの出力形式や緊急停止時の処理が変わらない限り、触る事はほとんどないでしょう。
そしてランタイムUNITのクラスは初期状態のままでいいのでメイン処理クラスで設定だけ済ませておいた上でランタイムUNITを作成するたびに動作確認していくのが順当かと思われます。
UNITパラメータクラスの方はUNIT処理の作成中にグローバルエリアの管理が必要になった時に実装を進める形でいいでしょう。