【新規開発環境】

はじめに

SOCKET‑MANAGER Framework の SimpleSocket(TCP/UDP)向け新規開発環境の構築ガイドです。
composer によるプロジェクト作成から SimpleSocketGenerator の初期設定、メイン処理クラスや設定・ロケールファイルの生成手順まで、実例を交えて短時間で開発を開始できる手順を解説します。

この環境では基本的なディレクトリ構成とライブラリしか入っていませんので、真っ新な状態から開発を始められます。
シンプルソケット機能(SimpleSocketGenerator)は、状態遷移を必要としない単純な送受信に特化し、TCP/UDP 通信をシンプルな構造で実装できます。

ここでは、環境のインストール手順と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.X.X

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 <メイン処理のクラス名>             メイン処理クラスの生成
 simple
  simple:tcp-server <メイン処理のクラス名>        TCPサーバー用メイン処理クラスの生成
  simple:tcp-client <メイン処理のクラス名>        TCPクライアント用メイン処理クラスの生成
  simple:udp <メイン処理のクラス名>               UDP通信用メイン処理クラスの生成
                    
laravel:commandコマンドに関してはLaravel環境でしか表示されません。

それでは動作確認のため、以下のコマンドを実行してメイン処理クラスを作成します。
今回はsimple:tcp-serverコマンドを使ってMainForTestという名前で作成します。

以下のように表示されれば成功です。
> php worker simple:tcp-server MainForTest

[success] TCPサーバーのメイン処理クラス生成に成功しました (MainForTest)
                    

再度php workerを実行してみます。
> php worker

SOCKET-MANAGER Framework 1.X.X

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 <メイン処理のクラス名>             メイン処理クラスの生成
 simple
  simple:tcp-server <メイン処理のクラス名>        TCPサーバー用メイン処理クラスの生成
  simple:tcp-client <メイン処理のクラス名>        TCPクライアント用メイン処理クラスの生成
  simple:udp <メイン処理のクラス名>               UDP通信用メイン処理クラスの生成
                     

アプリ名main-for-testという名前で登録されている事が確認できます。
まずは以下のコマンドを実行して今回作成したサーバーを起動した状態にしてください。
> php worker app:main-for-test 15000
                    

その後PowerShellなどで以下のようにnetstatコマンドを実行して15000ポートがListenされている事が確認できれば正常にインストールされています。
> netstat -ano | Select-String -Pattern "127.0.0.1:15000"

  TCP         127.0.0.1:15000        0.0.0.0:0              LISTENING       19216
                    


メイン処理クラスの生成

シンプルソケットでは以下の3種類のうちいずれかのメイン処理クラスを使います。
> php worker simple:tcp-server MainForTest

[success] TCPサーバーのメイン処理クラス生成に成功しました (MainForTest)
                    
※ TCPサーバーのメイン処理クラスに関する詳細は ▶TCP サーバーの実装 のページをご覧ください。
> php worker simple:tcp-client MainForTest

[success] TCPクライアントのメイン処理クラス生成に成功しました (MainForTest)
                    
※ TCPクライアントのメイン処理クラスに関する詳細は ▶TCP クライアントの実装 のページをご覧ください。
> php worker simple:udp MainForTest

[success] UDP通信のメイン処理クラス生成に成功しました (MainForTest)
                    
※ UDP 通信のメイン処理クラスに関する詳細は ▶UDP 通信の実装 のページをご覧ください。


生成されるクラスファイルはいずれも以下の場所に格納されます。
/app
    /MainClass
        MainForTest.php
                    


メイン処理クラスの中身

以下の内容は TCP サーバーのソースですが、SimpleSocketTypeEnum のタイプ(今回の場合は TCP_SERVER)や インターフェースインスタンス(今回の場合は ISimpleSocketTcpServer)の部分以外は共通です。
class MainForTest extends Console
{
    /**
     * @var string $identifer アプリケーション識別子
     */
    protected string $identifer = 'app:main-for-test {port_no?}';

    /**
     * @var string $description コマンド説明
     */
    protected string $description = 'Command description';


    /**
     * アプリケーション起動
     * 
     */
    public function exec()
    {
        // 引数の取得
        $port_no = $this->getParameter('port_no');

        /***********************************************************************
         * シンプルソケットジェネレータの初期設定
         * 
         * ジェネレータインスタンスの生成や各種設定をここで実行します
         **********************************************************************/
        $generator = new SimpleSocketGenerator(SimpleSocketTypeEnum::TCP_SERVER, 'localhost', $port_no);

        /**
         * ログライターの登録(任意)
         * 
         * ログライターが使いたい場合に$generator->setLogWriter()メソッドで登録します
         * SocketManager初期化クラスのログライターをそのままお使い頂けます
         */
        $generator->setLogWriter
        (
            /**
             * ログライター
             * 
             * @param string $p_level ログレベル(debug、info、notice、warning、errorなど)
             * @param array $p_param 連想配列形式のログ内容
             * @return void
             */
            function(string $p_level, array $p_param): void
            {
            }
        );

        /**
         * SocketManagerとの連携(任意)
         * 
         * UNITパラメータインスタンスの"simple_socket"プロパティにシンプルソケットインスタンスが設定され
         * コマンドディスパッチャーやステータスUNIT内で使えるようになります
         * 
         * $generator->setUnitParameter()メソッドでUNITパラメータクラスを設定します
         */

        /**
         * 常時実行処理の登録(任意)
         * 
         * 常時実行処理がある場合に$generator->setKeepRunning()メソッドで登録します
         */
        $generator->setKeepRunning
        (
            /**
             * 常時実行処理
             * 
             * @param ISimpleSocketTcpServer $p_simple_socket シンプルソケットインスタンス
             * @param mixed[] $p_argv 可変引数(setKeepRunningメソッドの第二引数以降のものが渡される)
             * @return void
             */
            function(ISimpleSocketTcpServer $p_simple_socket): void
            {
            }
        );

        /**
         * シンプルソケットインスタンスの生成
         * 
         * この手続きが行われた時点でインスタンスが生成され有効になります
         */
        $w_ret = $generator->generate();
        if($w_ret === null)
        {
            goto finish;
        }

        /***********************************************************************
         * シンプルソケットの実行
         * 
         * 周期ドリブン処理を実行します
         **********************************************************************/

        // ノンブロッキングループ
        while(true)
        {
            // 周期ドリブン
            $ret = $generator->cycleDriven();
            if($ret === false)
            {
                goto finish;
            }
        }

finish:
        $generator->shutdownAll();
        return;
    }
}
                    

いずれも任意ですが、ここで実装可能なのは以下の3点になります。
■ログライターの登録
$generator->setLogWriterメソッドでログライターを登録できます。

■SocketManagerとの連携
$generator->setUnitParameterメソッドでSocketManagerと連携できます。

■常時実行コールバックの登録
$generator->setKeepRunningメソッドで常時実行コールバックを登録できます。

※ メイン処理クラスの実装内容の詳細については、タイプごとに以下のページをご覧ください。

設定ファイルの作成

設定ファイルは以下のコマンドで作成できます。
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歳です。」という文字列を返します。

おわりに

SimpleSocketGenerator で生成される各インターフェースの詳細は以下のページをご覧ください。