[PHP]Ratchetの初期設定とテキストのリアルタイム通信テスト

2020年10月29日(更新: 2020年10月29日)

WebSocket による双方向リアルタイム通信を行えるPHPライブラリ「Ratchet」をXAMPPのローカルサーバーに設定し、実際に通信のチュートリアルを実行する手順についてです。

Ratchetのロゴ

公式ページ(Ratchet – Tutorial: Your first app)のチュートリアルドキュメントと違う操作が必要だった部分があったので、それについても記載します。

インストールのためにComposerを準備

Ratchet のインストールにはPHPライブラリ依存を管理するツールである「Composer」を利用するのが現実的です。Ratchet は複数のライブラリを使用しているため、一つひとつ手動でそれらを用意するのは大変だからです。

まず Composer のダウンロードページにアクセスします。

そのページに記載されているインストール用コマンドをターミナルにコピー&ペーストしてください。コマンドは以下のような形式ですが、変更される可能性があるので公式ページからコピーしてください。

PHPライブラリ依存管理ツール Composer のダウンロードコマンド

実際にターミナルに入力すると、以下のように出力され、インストールが完了します。

Composerのインストールが完了

インストールするディレクトリは任意ですが、今回はホームディレクトリ(~/)にインストールしています。以下のように composer.phar が追加されていることを確認してください。

以上で Composer の準備は完了です。

Ratchetをインストール

XAMPP の htdocs ディレクトリに任意の名前のフォルダを作成し、ターミナルでアクセスできる状態にします。この例では MyChat というフォルダ名にしています。

その後、ターミナルで次のコマンドを入力します。

php ~/composer.phar require cboden/ratchet

すると、ターミナルには以下のように出力されます。

Ratchetインストール時の出力

フォルダ内に以下のファイルが作成されます。

Composerを利用してRatchetをインストール

通信のための設定とスクリプトの作成

造られたファイルの中の composer.json を開き autoload の5行を追記します。require の部分は既に記述されているはずです。

{
    "autoload": {
        "psr-4": {
            "MyApp\\": "src"
        }
    },
    "require": {
        "cboden/ratchet": "^0.4.3"
    }
}

そして、ディレクトリ MyChat にフォルダ src/ を作成し、以下のPHPスクリプト(Chat.php)を作成します。

Chat.php

<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {
    public function onOpen(ConnectionInterface $conn) {
    }

    public function onMessage(ConnectionInterface $from, $msg) {
    }

    public function onClose(ConnectionInterface $conn) {
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
    }
}

さらに、同様にフォルダ bin/ を作成し、その中にスクリプト(chat-server.php)を作成してください。

chat-server.php

<?php
use Ratchet\Server\IoServer;
use MyApp\Chat;

    require dirname(__DIR__) . '/vendor/autoload.php';

    $server = IoServer::factory(
        new Chat(),
        8080
    );

    $server->run();

以上のスクリプトを作成後、ターミナルで以下のコマンドを入力してください。

php bin/chat-server.php

正常に動作するとターミナルには何も表示されないはずですが、以下のようなエラーが表示される場合があります。

Uncaught Error: Class 'MyApp\Chat' not found in 〜

Ratchetのエラー「Uncaught Error: Class 'MyApp\Chat' not found in」

もしこのエラーが表示されたなら composer.phar のアップデートを実行してみてください。アップデートのコマンドは以下のとおりです。

php ~/composer.phar update

composer.pharのアップデートでエラーを解消

正常に動作した場合は control+C で終了させてください。

Ratchetの正常動作を確認

以上で通信のための準備が整いました。

メッセージ送信の実行

実際に通信をテストするには、まず Chat.php を以下のように書き換えます。

Chat.php

<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        $numRecv = count($this->clients) - 1;
        echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
            , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');

        foreach ($this->clients as $client) {
            if ($from !== $client) {
                // The sender is not the receiver, send to each client connected
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);

        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "An error has occurred: {$e->getMessage()}\n";

        $conn->close();
    }
}

そして、ターミナルのウィンドウを3つ開き、それぞれ以下のコマンドを入力します。

php bin/chat-server.php
telnet localhost 8080
telnet localhost 8080

もし telnet がないと言われた場合は python を利用する以下のコマンドを試してみてください。

python -m telnetlib localhost 8080

実行結果です。一方のtelnetにメッセージを入力すると、他方にメッセージが表示されます。接続状態などは bin/chat-server.php を実行したウィンドウに表示されます。

Ratchetによる双方向通信の実行結果

ブラウザを利用したメッセージの送信

chat-server.php を以下のように書き換えます。

chat-server.php

<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;

    require dirname(__DIR__) . '/vendor/autoload.php';

    $server = IoServer::factory(
        new HttpServer(
            new WsServer(
                new Chat()
            )
        ),
        8080
    );

    $server->run();

ターミナルで再度 bin/chat-server.php を実行し、ブラウザのコンソールに以下のjavascriptを入力します。

var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
    console.log("Connection established!");
};

conn.onmessage = function(e) {
    console.log(e.data);
};

今回は GoogleChrome でテストしました。実行結果は以下のとおりです。

ブラウザのconsoleからRatchetでメッセージを送信

Ratchetでブラウザから送信されたメッセージを受信

ターミナルにブラウザから send によって送信したメッセージが表示されました。

以上、Ratchetの初期設定と、それを利用した通信の例でした。

コメントを残す

メールアドレスが公開されることはありません。