Ground Sunlight

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

ユーザ用ツール

サイト用ツール


サイドバー

メインメニュー

XAMPP アレンジ

IED

WSL2

道具箱

リポジトリ編

フレームワーク編

公開ソフトウェア

メタ
リンク


このページへのアクセス
今日: 5 / 昨日: 3
総計: 1695

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

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

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

Telnetを起動したコマンドプロンプトから、メッセージ( “Hello World!”)を入力すると、 他のウィンドウに表示されます。 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!” が表示されます。

コメント

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