はじめに
この記事でご紹介している環境はデモ版としてご紹介させて頂いたWebsocketサーバーからコマンド部を含めWebsocketに不要な部分を取り除いて再構築したものです。
プロトコルの主要な部分は実装済みなので、コマンド部を自分で作成しながらブラウザを使って動作確認できますので、新規でプロジェクトを起こす場合に比べてソケット通信初心者向けの環境と言えます。
デモ版の環境については以下のページでご紹介しています。
以降ではインストール方法と実装例を見ながら進めていきます。
環境
- プラットフォーム
- Windows10
- 統合環境
- Xampp v3.3.0
- ブラウザ
- Chrome v123.0.6312.123
- 言語
- PHP v8.2.4(v8.1.0以降)
ここではXAMPP環境を使っている前提で説明していますが、デフォルトとは別の場所に格納している場合やLinux等の別の環境で利用されている場合は適宜読み替えてください。
インストール
以下のコマンドでインストールできます。
> composer create-project socket-manager/websocket-project <インストール先のディレクトリ名>
GitHubから直接ダウンロードされる場合は以下のページからどうぞ。
それでは上記でインストールしたプロジェクトルートに移動して`php worker`コマンドを実行してみます。
> php worker
SOCKET-MANAGER Framework 1.0.0
Usage:
command [arguments]
main
app:websocket-server Websocketサーバー
craft
craft:init <初期化クラス名> 初期化クラスの生成
craft:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
craft:protocol <プロトコルUNIT定義のクラス名> プロトコルUNIT定義のクラスとステータス名Enumの生成
craft:command <コマンドUNIT定義のクラス名> コマンドUNIT定義のクラスとキュー/ステータス名Enumの生成
craft:main <メイン処理のクラス名> メイン処理クラスの生成
craft:setting <設定ファイル名> 設定ファイルの生成
craft:locale <メッセージファイル名> メッセージファイルの生成
ご覧のようにapp:websocket-server
が含まれている事が確認できます。
これを以下のように実行する事でサーバーを起動できます。
> php worker app:websocket-server [<ポート番号>]
コマンドの詳しい使い方は以下のページでご紹介しています。
実装例
ここではコマンド処理部分のチャットメッセージを実装してみます。
クライアントの実装
このプロジェクトではclient
ディレクトリに検証用として最低限の実装でファイルを同梱しています。
それではclient
ディレクトリ内のtest.js
を編集します。
test.js
内には以下のようにonopen
メソッドがあるのでここに処理を入れます。
// Websocket接続
websocket = new WebSocket(uri);
/**
* 接続完了イベント
*
* @param {*} event イベントインスタンス
* @returns
*/
websocket.onopen = function(event)
{
let data =
{
'cmd': 'message'
, 'comment': 'テスト'
};
websocket.send(JSON.stringify(data));
};
onopen
メソッドはWebsocketの接続が確立した時に呼び出されるイベントです。
上記のようにコマンド名はmessage
、送信コメントはテスト
にしてJSONデータを送信する処理を入れています。
そして以下のようにonmessage
メソッドで受信したデータを受け取れますので受信したデータはコンソールに表示されるようになっています。
/**
* データ受信イベント
*
* @param {*} event イベントインスタンス
* @returns
*/
websocket.onmessage = function(event)
{
let data = JSON.parse(event.data);
console.dir(data);
};
サーバーの実装
まずはCommandForWebsocketQueueEnum.php
のファイルに今回追加するコマンド名を定義します。
<?php
/**
* コマンド部のキュー名のENUMファイル
*
* Websocket用
*/
namespace App\CommandUnits;
/**
* コマンド部のキュー名定義
*
* Websocket用
*/
enum CommandForWebsocketQueueEnum: string
{
case MESSAGE = 'message';
}
次にCommandForWebsocket.php
を編集します。
class CommandForWebsocket implements IEntryUnits
{
/**
* @var const QUEUE_LIST キュー名のリスト
*/
protected const QUEUE_LIST = [
CommandForWebsocketQueueEnum::MESSAGE->value,
];
/**
* キューリストの取得
*
* @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 === CommandForWebsocketQueueEnum::MESSAGE->value)
{
$ret[] = [
'status' => CommandForWebsocketStatusEnum::START->value,
'unit' => $this->getMessageStart()
];
}
return $ret;
}
protected function getMessageStart()
{
return function(ParameterForWebsocket $p_param): ?string
{
$p_param->logWriter('debug', ['COMMAND:MESSAGE' => 'START']);
$w_ret = $p_param->getRecvData();
$msg = $w_ret['data'];
$data =
[
'data' => $msg
];
$p_param->setSendStackAll($data);
return null;
};
}
}
追加したポイントは以下の通り。
- ■QUEUE_LISTへEnum値を追加
- MESSAGEというキュー名を追加
- ■getUnitListメソッドの実装
- MESSAGEコマンドに対応するUNIT(メソッド)処理を登録
- ■getMessageStartメソッドの実装(※)
- 受信したデータを配信する処理を実装(上記ソース内のlogWriterメソッドでログ出力できます)
引数のParameterForWebsocket
クラスはSocketManagerParameter
クラスを継承しています。詳しくはSocketManagerParameter
クラスの>>Reference
をご覧ください。
動作確認
以下のコマンドを実行してサーバーを10000ポートで起動します。
> php worker app:websocket-server 10000
次にクライアントをブラウザで開きます。
client/test.html
をブラウザへドラッグ&ドロップした上でF12を押して以下の画面を開いてください。
この状態で接続ボタンをクリックすると以下のようにコンソール画面でメッセージコマンドが返ってきている事が確認できます。
そしてさらにブラウザをもう一つ開いて同じ操作をすると二つのブラウザウインドウに同じメッセージが配信されている事が確認できますので色々と試してみてください。
ログ出力について
以下のディレクトリ構成でログファイルが出力されます。
/logs
/socket-manager-log Websocketサーバーのログ
ファイルの命名規則は次の通り。
- ■Websocketサーバーのログ
- <日付文字列("Ymd"形式)>_W<ポート番号>.log
おわりに
コマンド処理は上記で実装したように以下の流れが基本となります。
- 1.受信データの取得
- getRecvDataメソッドで取得
- 2.送信データの作成
- シリアライズ前のデータを作成する
- 3.送信データの設定
- setSendStack、setSendStackAllメソッドで設定
Websocket開発環境では上記のようにコマンド部の処理を追加していく事でサーバーコンテンツを作成していく事になります。
以下のページであらかじめアーキテクチャの内容を理解して頂いた方がより高度な実装が可能になりますので興味のある方はご覧ください。
ホスト名やポート番号等の設定ファイルの詳細は以下のページでまとめています。
自作のプロトコルを実装する必要がある場合は以下の記事をご覧ください。
ここでご紹介したプロジェクトはLaravelと連携できます。
ご興味のある方は以下の記事をご覧ください。