Ground Sunlight

Windowsで作る - Webプログラミングの開発環境(PHP)

ユーザ用ツール

サイト用ツール


サイドバー

メインメニュー

XAMPP アレンジ

道具箱

リポジトリ編

フレームワーク編

公開ソフトウェア

メタ
リンク


このページへのアクセス
今日: 2 / 昨日: 1
総計: 16

ratchet:0.4:tutorial

Ratchet チュートリアル

Version 0.4.3

y2sunlight 2020-11-14

Ratchet に戻る

関連記事

リンク

本章は、Ratchet 公式サイトのチュートリアル(Hello World!)のレビューです。実際にチュートリアルを行った結果を補足とともに説明します。ここでは、PSR-4Composer に精通していることを前提としています。それらについては本編でも説明しているので、そちらをご覧ください。



プロジェクトの作成

まず、プロジェクトフォルダ(以下 {Project-Folder} と呼びます)を作成し、そこにComposerファイルを設置します。

composer.json
{
    "autoload": {
        "psr-4": {
            "MyApp\\": "src"
        }
    },
    "require": {
        "cboden/ratchet": "^0.4"
    }
}

上の設定では、プロジェクトフォルダ下の src フォルダにアプリケーションを設置し、そこを MyApp 名前空間として定義します。 Composer の規則に従い、ratchet は vender/cboden/ratchet 下に保存されます。また、チャットサーバ起動用のスクリプトを配置する bin フォルダを作ります。

プロジェクトフォルダ下に以下のフォルダを作成します:

  • src — アプリケーションソースを格納します
  • bin — アプリケーション起動用のスクリプトを格納します

準備が出来たら、コマンドプロンプトでプロジェクトフォルダに移り、composer install を実行します。

> composer install

Loading composer repositories with package information
Warning from https://repo.packagist.org: You are using an outdated version of Composer. Composer 2.0 is now available and you should upgrade. See https://getcomposer.org/2
Updating dependencies (including require-dev)
Package operations: 18 installs, 0 updates, 0 removals
  - Installing symfony/polyfill-php80 (v1.20.0): Downloading (100%)
  - Installing symfony/deprecation-contracts (v2.2.0): Downloading (100%)

...

Writing lock file
Generating autoload files


チャットアプリの外観

チュートリアルでは、簡単なチャットアプリケーションを作成します。それは、すべての着信メッセージを受け入れ、そのメッセージを他のすべての接続に配信するだけのものです。送信メッセージは、お決まりの 「HelloWorld!」 にしましょう。

Chat クラス

まず、アプリケーション本体になる Chat クラスをsrcフォルダの下に作成します。

{Project-Folder}/src/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) {
    }
}

このクラスは、MessageComponentInterface を実装し、次の4つのイベントハンドラを作ります。

  • onOpen - 新しいクライアントが接続したときに呼び出されます
  • onMessage - 接続がメッセージを受信したときに呼び出されます
  • onClose - 接続が閉じられたときに呼び出されます
  • onError - 接続でエラーが発生したときに呼び出されます

こられのイベントハンドラは、ConnectionInterface オブジェクトを引数に持っています。それは、ソケットの反対側のクライアントの接続を表しています。

インスタンス化

Chat クラスは、実際のアプリケーションロジックを含みますが、これをインスタンス化するスクリプト ( チャットサーバと呼ぶ事にします ) を作ります。このスクリプトは、コマンドラインから呼び出されます。

{Project-Folder}/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();

ここでは、IoServer を作成しています。

IoServer はチャットアプリケーションのベースとなるイベント処理を行う中核のサーバクラスです。IoServer クラスは、確立されたすべての接続を保存し、各クライアントとチャットアプリケーション間で送信されるデータを仲介します。また、エラーがあればそれをキャッチします。

ここでは、Chatクラスの新しいインスタンスが IoServer をラップし、ポート8080で着信要求をリッスンしてイベントループに入るようにサーバーに指示します。

コマンドプロンプトを起動しプロジェクトフォルダに移動し、bin/chat-server.php を起動します:

php bin/chat-server.php

次に、別のコマンドコマンドプロンプトを起動し以下のコマンドを実行します。

netstat -an | find "8080"

以下のようにリスニングポートが開いていたらOKです。

  TCP         0.0.0.0:8080           0.0.0.0:0              LISTENING

まだプログラムは完成していないのでこれ以上は何も起こりません。Ctrl + c でスクリプトを停止して下さい。


チャットロジックの実装

先に作成した Chat クラスのスケルトンにロジックを追加します。

メッセージを送信するために着信の接続を追跡し、ここでは SplObjectStorage と呼ばれるコンテナに格納します。このストレージコンテナは、オブジェクトを格納するように構築されています。

SplObjectStorage は、PHP 5.2 以降に搭載された便利なコンテナクラスです。

{Project-Folder}/src/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();
    }
}
  • __construct — SplObjectStorageオブジェクトを作成します
  • onOpen — 着信した接続を SplObjectStorageオブジェクトに格納します
  • onMessage — 送信者以外の全ての端末に、着信メッセージを送信します
  • onClose — SplObjectStorageオブジェクトからクローズされた接続を除外します
  • onError — エラーの発生した接続を閉じます

非常にシンプルなロジックですが、Ratchet の MessageComponentInterface を理解するには良い例題です。


チャットアプリの実行

アプリケーションが完成したので、実行してみましょう。

まず、コマンドプロンプトでチャットサーバ (chat-server.php) を起動します。

php bin/chat-server.php

別のコマンドプロンプトから以下のようにTelnetを起動します。

Telnet が有効になっていない場合は、こちらをご覧下さい。
telnet localhost 8080

この時、チャットサーバから以下のメッセージが出力されます。

New connection! (37)

さらに、別のコマンドプロンプトからもTelnetを起動します。

telnet localhost 8080

上と同じように、チャットサーバから2番目のメッセージが出力されます。

New connection! (37)
New connection! (48)

Telnetを起動した一方のコマンドプロンプトから、メッセージ( Hello World! )を入力すると、他方のウィンドウにメッセージが表示されます。尚、Telnetを終了するには、ctrl + ] でコマンドモードに移行し、quit コマンドを入力します。

ここまではTCPレベルのアプローチです。主な機能は MessageComponentInterface に集約されており、イベントハンドリングが主体で、WebSocketAPI はまだ機能していません。


WebSocketへの対応

基本的なチャットアプリケーションが機能するようになったので、今度はWebブラウザでそれが機能するようにチャットサーバを変更します。

{Project-Folder}/bin/chat-server-ws.php

chat-server-ws.php
<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
 
require dirname(__DIR__) . '/vendor/autoload.php';
 
$ws = new WsServer(new MyChat);
 
$server = IoServer::factory(
    new HttpServer($ws),
    8080
);
 
$server->run();

WsServer を使用すると W3C WebSocketAPI を使用するWebブラウザーと通信できるようになります。HttpServer は、着信HTTPリクエストの解析を担当します。このクラスの目的は、完全なHTTPヘッダー要求を受信して渡すまでデータをバッファリングすることで、 WebSocket リクエストをアップグレードするためのものです。

このチャットをテストするために、次のファイルを作ります。(HTMLファイルでも問題ありません)

{Project-Folder}/src/test-ws.php

client-ws.html
<script type="text/javascript">
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
    console.log("Connection established!");
};
 
conn.onmessage = function(e) {
    console.log(e.data);
};
</script>

コマンドプロンプトでチャットサーバ(chat-server-ws.php)を実行します。

php bin/chat-server-ws.php

次に、2つのブラウザウィンドウを開いて test-ws.php にアクセスし、ブラウザの開発ツールを開いて下さい。そして、デバックコンソールに次のメッセージが出力されていることを確認して下さい。

Connection established!

このメッセージが出ていたら、一方のブラウザのデバックコンソールから次のコードを実行します:

conn.send('Hello World!');

この時、他方のデバックコンソールに “Hello World!” が表示されます。

これで Ratchet のチュートリアル「Hello World!」を終わります。


コメント

コメントを入力. Wiki文法が有効です:
 
ratchet/0.4/tutorial.txt · 最終更新: 2020/11/19 11:09 by y2sunlight