やりたいこと
- WordPressの情報を使うNode.jsのサーバアプリケーションを動かしたい
- Socket.IOサーバーを立ててチャットとか
- もろもろの管理を簡略化したいのでWordPressプラグインとして実装
- プラグインを有効化・無効化したタイミングで、起動・停止とかしたい
詰まったところ
普通に呼んだだけだと終了を待ってしまう
プラグイン有効化イベントに対してexec関数で単純に exec('node app.js')
というような処理をフックしただけだと、呼び出したnodeのプロセスが閉じるまでPHPがハングします。
それでも起動するにはするのですが、嫌な感じです。
簡単にforkさせてくれない
PHPには子プロセスを走らせるためのforkなる仕組みがあるらしいので使おうとしてみたのですが、想定する動作をさせることができませんでした。
PHPのフォークはちょっと癖が強いようです。
Windows環境下だとさらにちょっと面倒
開発環境がWindowsなので、Windowsでも動作するようにしようと思ったのですが、バックグラウンドプロセスとして走らせるためのコマンドがよくわからない。
Linuxだと&
で放り投げておけばいいんですが。
実装
wp-chat.php
<?php
/*
* Plugin Name: WPChat
* Description: WordPressのユーザー情報を利用してチャットができるようにするプラグインです。
* Version: 0.1;
* Author: Huruikagi
* Author URI: https://github.com/Huruikagi
*/
// プラグインが有効になった際の処理
function on_activate() {
// Node.jsでチャット用のサーバーを起動する処理
// エントリポイントのパス
$path = join(DIRECTORY_SEPARATOR, array(__DIR__, 'chat-server', 'express', 'app.js'));
if (PHP_OS === 'WIN32' || PHP_OS === 'WINNT') {
// windowsのとき
$command = "node $path > nul 2>&1";
$fp= popen("start /B cmd /c $command", "r");
pclose($fp);
} else {
// unix系の時
$command = "node $path";
exec("$command >/dev/null 2>&1 &");
}
}
register_activation_hook(__FILE__, 'on_activate');
// プラグインが無効になったときの処理
function on_deactivate() {
// サーバー停止リクエストを投げる
// TODO URLを設定情報から読み出す
file_get_contents("http://localhost:8888/kill");
}
register_deactivation_hook(__FILE__, 'on_deactivate');
ポイント
- exec内で呼び出すプロセスの出力をnullに投げ捨てさせればオッケー
- PIDを記録してkillするのは面倒なので特定のHTTPリクエストが来た時に自分から死ぬようにしてみた